添加列:默认加在末尾,但可指定位置
MySQL 的
ALTER TABLE ... ADD COLUMN默认把新列追加到表结构最右边。这通常够用,但若业务逻辑依赖字段顺序(比如导出 CSV、ORM 映射或旧脚本硬编码列序),就容易出错。
实操建议:
加在指定列之后:ALTER TABLE user ADD COLUMN phone VARCHAR(20) AFTER email;加在最前面:
ALTER TABLE user ADD COLUMN id_new BIGINT FIRST;批量加多个字段,推荐用括号语法(MySQL 8.0.19+):
ALTER TABLE em_day_data ADD (f_hour1 INT, f_hour2 INT, f_hour3 INT);,比写多条
ADD更高效、更原子 加字段前务必确认字符集和排序规则(如
utf8mb4_unicode_ci),否则可能引发隐式转换或索引失效
删除列:不可逆,且主键/索引关联列要先处理
DROP COLUMN是高危操作——它直接删掉整列数据,且无法通过
ROLLBACK恢复(即使在事务里)。更麻烦的是,如果该列是主键、唯一索引、外键或自增列的一部分,MySQL 会直接报错。
常见错误现象:
ERROR 1091 (42000): Can't DROP 'xxx'; check that column/key exists或更隐蔽的
ERROR 1025 (HY000)(常因外键约束触发)。
实操建议:
先查依赖:SHOW CREATE TABLE user;看是否有
PRIMARY KEY、
UNIQUE KEY、
FOREIGN KEY涉及该列 删主键列?必须先删主键:
ALTER TABLE haha DROP PRIMARY KEY;;若带
AUTO_INCREMENT,还得先去掉自增:
ALTER TABLE haha MODIFY id INT;生产环境务必先备份表:
CREATE TABLE user_bak AS SELECT * FROM user;
修改列名或类型:CHANGE 和 MODIFY 不是等价替换
CHANGE和
MODIFY都能改列,但行为差异极大:
CHANGE必须写「原列名 + 新列名 + 完整定义」,哪怕只改注释;而
MODIFY只需写新定义,不能改名。
使用场景:
只调类型/长度/注释(不改名)→ 用MODIFY:
ALTER TABLE user MODIFY username VARCHAR(64) NOT NULL COMMENT '登录账号';要重命名 → 必须用
CHANGE,且新列名不能省:
ALTER TABLE user CHANGE username login_name VARCHAR(64) NOT NULL COMMENT '登录账号';想只改注释?仍得用
CHANGE,列名写成一样:
ALTER TABLE user CHANGE status status TINYINT NOT NULL COMMENT '1=启用,0=禁用';
注意:
CHANGE会重建字段,对大表可能锁表数分钟;
MODIFY在某些类型变更(如
VARCHAR长度增大)时也可能触发全表拷贝。
清空 vs 删除 vs 重命名:别混淆 delete、drop 和 rename
新手常把
DELETE FROM table当成删表——其实它只是清空数据,表结构、索引、权限全留着;而
DROP TABLE是物理删除整个表;
RENAME TABLE则是秒级元数据操作,适合灰度切换。
关键区别:
DELETE FROM user;→ 行级日志,可回滚,但慢、占 binlog、不释放磁盘空间
TRUNCATE TABLE user;→ DDL 操作,不可回滚,快、清空空间、重置自增计数器(但会失败于有外键引用的表)
DROP TABLE user;→ 彻底消失,连
CREATE TABLE语句都丢了,除非你有备份
RENAME TABLE user TO user_old;→ 零停机迁移常用,配合
CREATE TABLE user AS SELECT ...建新表后原子切换
真正危险的不是语法记错,而是没意识到
ALTER TABLE在 MySQL 中多数情况会锁全表(尤其老版本),大表操作务必避开高峰,并提前在从库验证执行耗时。
