表设计回头看多了个用不上的列,想清掉又怕手滑出事。mysql 删除字段就是一句 alter table 的事,但删之前有件事必须先做:备份。
动手前先看清现状
不确定列里有没有数据、有没有索引,先跑 desc users 看表结构,或者用 show create table 看完整的建表语句,索引、默认值、注释都在里面。顺便看一眼列上有没有自增、默认值这类属性,以后想加回同名列时用得上。列上挂着索引的,删列时索引会跟着一起删掉,这个行为要提前知道。
基本写法
alter table users drop column age;执行完这一列和里面的数据就没了,没有任何回收站可捞。列名拼错会报 unknown column,检查一下拼写,别把表名当成列名写进去。要一次删多个字段,可以这样写:
alter table users drop column age, drop column phone;删之前的三件事
- 备份:用 mysqldump 把这张表导出一份,或者至少把要删的列 select 出来存档
- 确认依赖:代码里还有没有语句引用这一列,视图、存储过程、报表里用没用
- 处理外键:有外键指向这一列的,先删约束再删列,否则语句直接报错
- 评估表大小:行数多的表删列一般要重建,期间写入会受影响
大表要单独考虑
MySQL 8.0 的部分新版本对删列做了优化,某些场景能走轻量算法,秒级完成;更老的版本是实打实重建整张表,千万行的表可能锁几十分钟。上线前先在测试库按同样的数据量跑一遍,线上挑业务低峰执行,主从架构下还要留意主从延迟会不会被放大。磁盘空间也要留够,重建期间旧表新表同时占着空间,余量不足会直接失败。
稳妥的做法是分两步走:先在代码里下掉对这一列的所有引用,观察一个版本周期没报错,再执行删列,风险最小。多删几个字段时写一条语句比写多条好,重建只发生一次。
mysql 删除字段之后想反悔,数据是找不回来的,只能从备份恢复。所以别嫌备份麻烦,drop column 敲回车之前,备份永远排在第一位,这句话在每个项目里都适用。