应使用 modify column 而非不存在的 alter column;仅改类型、长度或约束(如加 not null)时用 modify column,语义清晰且轻量;改字段名兼类型时才用 change column。

直接用 MODIFY COLUMN,别用 ALTER COLUMN —— 后者在 MySQL 中根本不存在,是常见误写。
什么时候该用 MODIFY COLUMN 而不是 CHANGE COLUMN
只改类型、长度或约束(比如加 NOT NULL、改 DEFAULT),就用 MODIFY COLUMN。它语义干净,不碰字段名,执行也更轻量。
CHANGE COLUMN 的唯一正当用途是:要同时改字段名和类型(例如把 user_name 改成 username 并扩到 VARCHAR(255))。哪怕你“名字不变”,也得写两遍字段名,MySQL 不会优化掉这个字符串比较。
- 想把
age从TINYINT升级为SMALLINT:用ALTER TABLE users MODIFY COLUMN age SMALLINT - 想把
status从VARCHAR(20)改成ENUM('active','inactive'):仍用MODIFY COLUMN,但要注意枚举值删减风险 - 误写成
CHANGE COLUMN age age INT—— 语法合法,但多一次无意义的字段名比对,没必要
改类型时最容易漏掉的约束:NOT NULL
MySQL 不会继承原字段的约束。如果原字段是 NOT NULL,而你在 MODIFY COLUMN 里没显式写上,新字段就会变成允许 NULL。
- 原定义:
email VARCHAR(100) NOT NULL - 错误写法:
ALTER TABLE users MODIFY COLUMN email VARCHAR(255)→ 新字段变成NULLable - 正确写法:
ALTER TABLE users MODIFY COLUMN email VARCHAR(255) NOT NULL - 验证方式:
DESCRIBE users或SHOW COLUMNS FROM users,盯紧Null列
大表改类型卡住?先看是不是真在 copy 数据
MySQL 8.0.12+ 的 ALGORITHM=INSTANT 对改类型基本无效;绝大多数类型变更仍需 INPLACE(重建索引)或全表 COPY。真正卡住往往是因为:
-
SHOW PROCESSLIST显示状态长期停在copy to tmp table—— 这是全量拷贝,IO 和锁都重 - 字段上有全文索引、空间索引或函数索引,会强制降级为
COPY - 目标类型不兼容现有数据(比如把含字母的
VARCHAR改成INT),报错前可能已锁表数秒 - 线上大表建议用
pt-online-schema-change,但它要求表有主键、无外键依赖,且会额外占用磁盘空间
真正麻烦的从来不是语法写错,而是改完才发现某列历史数据里混着超长字符串、空格结尾的枚举值,或者默认值逻辑被悄悄覆盖了——动手前先 SELECT 抽样检查,比反复 rollback 更省时间。











