mysql对已有数据的字段添加not null约束时,若存在null值会报错,必须先清理或填充null值再执行alter table;推荐用change column替代modify column以避免类型遗漏,并注意大表操作的锁和性能影响。

ALTER TABLE 时直接加 NOT NULL 会报错
MySQL 在对已有数据的字段添加 NOT NULL 约束时,如果该列存在 NULL 值,会直接拒绝执行并报错:ERROR 1265 (01000): Data truncated for column 'xxx' at row N 或更明确的 ERROR 1138 (22004): Invalid use of NULL value。这不是语法问题,而是数据校验失败——MySQL 要求全表该列值都非空,才能成功添加约束。
必须先清理或填充 NULL 值再加约束
核心操作顺序不可颠倒:先确保列中无 NULL,再执行 ALTER TABLE ... MODIFY COLUMN ... NOT NULL。具体分三步:
- 查出哪些行是
NULL:SELECT id FROM your_table WHERE your_column IS NULL; - 根据业务决定填充策略(不能随便用默认值掩盖逻辑):
– 若字段有自然默认含义(如状态字段),用合理业务值更新:UPDATE your_table SET your_column = 'active' WHERE your_column IS NULL;
– 若无法推断,且允许空字符串或零值,需确认应用层是否兼容:UPDATE your_table SET your_column = '' WHERE your_column IS NULL;
– 不建议用0或'0'填充文本字段,易引发语义混淆 - 执行约束变更:
ALTER TABLE your_table MODIFY COLUMN your_column VARCHAR(50) NOT NULL;(注意:MODIFY COLUMN需重写整列定义,类型和长度必须显式写出,不能只写约束)
使用 CHANGE COLUMN 替代 MODIFY COLUMN 更安全
当字段名不变但要改约束时,CHANGE COLUMN 和 MODIFY COLUMN 效果一致,但前者强制要求写出新旧字段名,能避免因漏写类型导致意外截断或隐式转换。例如:
ALTER TABLE your_table CHANGE COLUMN your_column your_column VARCHAR(50) NOT NULL;
相比 MODIFY,它更清晰地表明“这是同一字段”,也更容易在脚本中做 diff 对比。另外,若字段带索引或外键,MySQL 会自动保留这些关联,但建议操作前用 SHOW CREATE TABLE your_table 确认当前结构。
线上表慎用,尤其大表要考虑锁与性能
MySQL 5.6+ 对 ALTER TABLE ... MODIFY COLUMN 支持 ALGORITHM=INPLACE(仅限部分场景),但只要涉及列定义变更(包括加 NOT NULL),仍可能触发表重建,导致长时间的元数据锁(MDL)和写入阻塞。真实影响取决于数据量:
- 几万行以内:通常秒级完成,影响小
- 千万级以上:可能卡住写操作数分钟,必须安排在低峰期,并提前在从库验证耗时
- 若不能停写,考虑分批更新 + 应用双写过渡,而不是强求单条
ALTER
真正容易被忽略的是:即使你填了所有 NULL,如果该列之前是 TEXT 或 BLOB 类型,加 NOT NULL 不会报错,但后续插入空字符串时可能触发严格模式下的警告——得看 sql_mode 是否含 STRICT_TRANS_TABLES。











