modify column改类型或长度需重写完整字段定义(含约束),否则会丢失not null、default等;改名必须用change column,且须同时指定新旧列名和完整新定义。

直接说结论:用 MODIFY COLUMN 改类型和长度最常用,但必须写全字段定义(包括类型、长度、是否允许 NULL、默认值等),否则可能意外丢掉约束;改名+改类型则必须用 CHANGE COLUMN。
MODIFY COLUMN 必须重写完整字段定义
很多人以为 MODIFY COLUMN city VARCHAR(50) 只是加长长度,其实它会把原有字段的 NOT NULL、DEFAULT、COMMENT 全部清空——除非你显式写出来。
- 错误写法(丢失 NOT NULL 和 DEFAULT):
ALTER TABLE address MODIFY COLUMN city VARCHAR(50); - 正确写法(保留原有约束):
ALTER TABLE address MODIFY COLUMN city VARCHAR(50) NOT NULL DEFAULT '' COMMENT '城市名称'; - 如果原字段是
TEXT,想改成MEDIUMTEXT,也得写全:ALTER TABLE news MODIFY COLUMN content MEDIUMTEXT;(TEXT本身不支持长度,但MEDIUMTEXT是独立类型) - 缩小长度风险极大:从
VARCHAR(200)改成VARCHAR(50)时,超长数据会被截断且无警告,执行前务必先查:SELECT id, city FROM address WHERE LENGTH(city) > 50;
CHANGE COLUMN 适合改名或同时调整类型+长度
CHANGE COLUMN 强制要求写出「旧名、新名、完整新定义」,天然避免漏写约束,但语法稍啰嗦。
- 只改名不改类型:
ALTER TABLE user CHANGE COLUMN name nick_name VARCHAR(50) NOT NULL DEFAULT '' COMMENT '昵称';(注意:即使类型不变,也要重复写一遍) - 改名+扩长度+加默认值一步到位:
ALTER TABLE product CHANGE COLUMN desc description TEXT NOT NULL DEFAULT ''; - 不能只写
CHANGE COLUMN a b(缺类型会报错),MySQL 不支持纯重命名语法 - 性能上,
CHANGE和MODIFY对大表都是全表拷贝重建,耗时相近,别指望哪个更快
小数点位数修改必须用 MODIFY 或 CHANGE
DECIMAL(M,N) 的 M(总位数)和 N(小数位)属于类型定义的一部分,不能单独“调小数点”,只能整体替换类型。
- 把
price DECIMAL(10,2)改成DECIMAL(12,4):ALTER TABLE order_item MODIFY COLUMN price DECIMAL(12,4); - 如果原字段有
NOT NULL,但新语句没写,就会变成允许 NULL —— 这类隐性变更在线上最容易引发应用层空指针 - 扩大
N一般安全;但缩小N(如从DECIMAL(10,4)→DECIMAL(10,2))会导致四舍五入,且不报错,需提前验证数据影响范围
真正容易被忽略的是:无论用 MODIFY 还是 CHANGE,只要涉及类型变更,MySQL 都会尝试转换现有数据。比如把 VARCHAR 改成 INT,遇到非数字内容就直接失败;而 VARCHAR(10) 改成 VARCHAR(5) 却只截断不报错。这类行为差异不是 bug,是设计如此——所以每次执行前,先用 SELECT 检查数据分布,比背熟语法重要得多。











