大表修改表结构
方案1:直接alert table *** ***
这个方案是最基本的也是最简单的,但是有个弊端,如果这个表非常非常的大,会在经过一段时间之后报错
错误内容:The total number of LOCKS exceeds the LOCK TABLE size
这时候你需要修改mysql的配置,要增大 innodb_buffer_pool_size 这个参数,如果没权限直接使用第二方案,但是这个参数也是有上限的,如果你的表实在太大,内存占满了也还是失败,那就换方案
方案2:拷贝数据
这个方案的执行方法就是先建一张和原来的表一模一样的表,然后对这张表进行修改表结构,到这边都很快,然后做数据拷贝
创建copy表:create table copyTable (id int(10) unsigned NOT NULL AUTO_INCREMENT, *** *** ***) 注意:AUTO_INCREMENT 这个配置可以配置的高一些,如果已经完全停止了服务可以忽略这一步
修改表结构:alter table copyTable *** *** ***
copy数据到新表:INSERT INTO `image_regions`(id,***,***,***) SELECT id,***,***,*** FROM `image_regions_old`,如果是大表,这个拷贝会消耗比较长的时间,但是相对于直接修改表结构速度会快上好多
修改老表的名字:alter table old_table rename to old_table_tmp
修改新表的名字:alter table new_table rename to old_table
如果的在停止服务的时候做这件事情,那到这里就已经结束了
如果你在做这个的时候有人还在操作数据,或者,在做这个的时候,有些服务忘记关了,那么就会引发一些问题
这个表在拷贝数据的时候有新的数据进入到旧表,如果这个表和其他的表又有数据关联,比如说外键关联,或者什么其 他的业务逻辑上的联系,会导致数据不一致,外键关联的话就很简单,会直接报错,
"23000",1452,"Cannot add or update a child row: a foreign key constraint fails
导致这个错误的原因就是因为在老表里已经新建了一些字段,但是新表里没有,但是外键关联什么的还是已经有了
解决方案:一般来讲,删除主表不存在的,或者在主表上加上老表上已有的就可以的,
需要删除内容查找:select * from tableA as a left join tableB as b on a.fk = b.id where b.id is null
但是有时候还是会有其他的问题,比如数据库里自带的外键验算规则,这时候,就需要删除外键关联
ALTER TABLE table DROP FOREIGN KEY foreign_key
当然在这之前你还是需要把数据先fix好,之后再把外键加回去
大功告成