声明:本答案基于MySQL,可能不适用于其他数据库。
我认为接受的答案中缺少一些东西,我试图在这里介绍一种我在生产环境中使用的通用序列,不仅用于添加/删除列,还可用于添加索引等操作。
我们称之为印第安纳琼斯式移动。
创建一个新表格
使用旧表格作为模板创建一个新表格:
create table my_table_new like my_table;
移除新表中的列
在新表中:
alter table my_table_new drop column column_to_delete;
向新表中添加外键
这些不会在create table like
命令中自动生成。
您可以检查实际的外键:
mysql> show create table my_table;
然后将它们应用到新表中:
alter table my_table_new
add constraint my_table_fk_1 foreign key (field_1) references other_table_1 (id),
add constraint my_table_fk_2 foreign key (field_2) references other_table_2 (id)
克隆表格
复制除需要删除的字段之外的所有字段。
我使用 where
语句,以便如果需要,可以多次运行此命令。
由于我假设这是一个生产环境,因此 my_table
将不断有新记录,所以我们必须保持同步,直到我们能够更改名称。
此外,我添加了一个 limit
,因为如果表太大且索引太重,则一次性克隆可能会关闭数据库的性能。而且,如果在过程中想要取消操作,则必须回滚所有已完成的插入,这意味着你的数据库无法立即恢复 (https://dba.stackexchange.com/questions/5654/internal-reason-for-killing-process-taking-up-long-time-in-mysql)
insert my_table_new select field_1, field_2, field_3 from my_table
where id > ifnull((select max(id) from my_table_new), 0)
limit 100000;
我多次执行此操作后创建了一个过程:https://gist.github.com/fguillen/5abe87f922912709cd8b8a8a44553fe7
更改名称
请确保在复制表中的最后记录后立即运行此命令。理想情况下,一次运行所有命令。
rename table my_table to my_table_3;
rename table my_table_new to my_table;
删除旧表格
在进行此操作之前,请确保已备份 ;)
drop table my_table_3
免责声明:我不确定指向旧表的外键会发生什么。