大表修改表结构

大表修改表结构

方案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好,之后再把外键加回去

大功告成

你可能感兴趣的:(sql)