MySQL 5.7及更早版本必须用ALTER TABLE ... CHANGE修改字段名,因不支持RENAME COLUMN;CHANGE需重复写旧名与新名并显式重申全部属性(类型、NULL/NOT NULL、DEFAULT、COMMENT等),否则会导致空值允许、默认值或注释丢失,且会锁表重建。

用 ALTER TABLE ... CHANGE 是唯一稳妥方式
MySQL 5.7 及更早版本根本不支持 RENAME COLUMN,强行写会直接报错 ERROR 1064 (42000);即使在 8.0+,RENAME COLUMN 也仅限纯改名,一旦字段带 NOT NULL、DEFAULT 或 COMMENT,它就失效。真正能兼顾重命名+保留全部属性的,只有 CHANGE。
它的本质是「删旧列 + 建新列」,所以必须显式写出完整定义——类型、空值性、默认值、注释一个都不能少,否则会静默降级(比如原为 NOT NULL,漏写就变成 NULL)。
- 先查清原字段完整定义:
SHOW CREATE TABLE table_name;,复制那一行CREATE TABLE中对应字段的完整声明 - 把旧字段名替换成新字段名,其余部分一字不改(包括括号、空格、大小写)
- 执行前确认表上无长事务,避免锁表阻塞业务
CHANGE 必须重复写两次字段名,且顺序不能颠倒
语法是 ALTER TABLE t CHANGE old_col new_col TYPE ...,第一个是旧名,第二个是新名。很多人写成 CHANGE new_col old_col ...,结果 MySQL 真的会按字面意思把新名当旧名去删——轻则字段消失,重则误删数据。
示例:要把 users 表中 user_name 改成 username,原字段定义是 user_name VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户昵称',正确写法是:
ALTER TABLE users CHANGE user_name username VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户昵称';
漏掉 NOT NULL?改完字段突然允许空值,下游 INSERT 不带该字段就可能失败;漏掉 COMMENT?文档和 ORM 映射全丢;漏掉 DEFAULT ''?已有记录该字段值全变 NULL。
大表改名务必避开高峰期,否则业务会卡住
ALTER TABLE ... CHANGE 在大多数 MySQL 版本中会触发表重建(即使只是改名),期间对整张表加元数据锁(MDL),所有读写都会排队等待。一张千万级的 orders 表执行一次,可能卡住 3–5 分钟。
- 确认是否支持
ALGORITHM=INSTANT:仅限修改列名且不改类型/约束时可用,但要求 MySQL ≥ 8.0.12 且引擎为 InnoDB;执行前加ALGORITHM=INSTANT显式声明,否则默认走 COPY - 生产环境优先选低峰期,如凌晨 2–4 点;若无法停机,考虑用
pt-online-schema-change工具在线改 - 改完立刻验证:
SELECT COUNT(*) FROM table_name WHERE new_col IS NULL;检查是否意外引入空值
别碰 RENAME DATABASE,它已被移除且不可逆
网上很多教程还教用 RENAME DATABASE old TO new,这是个危险误区——该语句早在 MySQL 5.7.6 就被彻底移除,现在执行只会报错 ERROR 1064。官方明确推荐用 mysqldump 导出再导入,或跨库 ALTER TABLE db1.t1 RENAME TO db2.t1 搬迁。
真正需要改库名时,最容易被忽略的是权限迁移:原库的用户授权(GRANT 记录)不会自动跟着库名走,必须手动用 SHOW GRANTS FOR 'user'@'host'; 查出后,把旧库名替换成新库名再执行一遍 GRANT。


















