mysql中添加default必须随字段定义显式声明,如modify column status varchar(20) default 'active';它仅影响后续insert未指定该字段或显式写default的行,不修改历史数据。

ALTER TABLE 添加 DEFAULT 时语法写错
最常见的错误是把 DEFAULT 当成独立语句或写在错误位置。MySQL 要求它必须紧跟在字段定义之后,且不能单独用 ALTER TABLE ... DEFAULT 这种写法。
正确做法是用 MODIFY COLUMN 或 CHANGE COLUMN 重新声明字段,并带上 DEFAULT 子句:
ALTER TABLE users MODIFY COLUMN status VARCHAR(20) DEFAULT 'active';
如果字段已有数据,加默认值不会影响现有行;但后续插入不显式指定该字段时,才会生效。
-
MODIFY COLUMN适合只改属性(如类型、默认值),不改列名 -
CHANGE COLUMN要求重写列名(哪怕不变),语法更啰嗦:CHANGE COLUMN status status VARCHAR(20) DEFAULT 'active' - 对
NOT NULL字段加DEFAULT没问题;但对已存在NULL值的字段设DEFAULT,新默认值仅对后续插入生效,旧NULL不会自动更新
INSERT 不指定字段时 DEFAULT 才触发
很多人误以为设了 DEFAULT 就能“填充历史空值”,其实不是。MySQL 的 DEFAULT 是插入时的兜底策略,不是数据清洗工具。
只有两种情况会用到默认值:
- INSERT 语句完全不提该字段:
INSERT INTO users (name, email) VALUES ('Alice', 'a@b.c'); - INSERT 显式用
DEFAULT:INSERT INTO users (name, status) VALUES ('Bob', DEFAULT);
如果写了 NULL 或空字符串,哪怕字段有 DEFAULT,也不会触发——MySQL 认为你就是想存 NULL 或 ''。
TIMESTAMP 和 DATETIME 的 DEFAULT 行为差异大
这两个类型对 DEFAULT 的处理逻辑完全不同,容易踩坑:
-
TIMESTAMP支持DEFAULT CURRENT_TIMESTAMP和ON UPDATE CURRENT_TIMESTAMP,且最多只能有一个字段用CURRENT_TIMESTAMP作默认值(MySQL 5.6.5+ 放宽限制,但仍有约束) -
DATETIME在 MySQL 5.6.5 之前不支持函数默认值;5.6.5+ 起支持DEFAULT CURRENT_TIMESTAMP,但不支持ON UPDATE(除非用触发器模拟) - 如果字段定义为
TIMESTAMP NOT NULL且没设DEFAULT,MySQL 会偷偷加DEFAULT CURRENT_TIMESTAMP—— 这是隐式行为,容易导致意外时间戳
建议显式写清:created_at DATETIME DEFAULT CURRENT_TIMESTAMP,避免依赖隐式规则。
JSON 字段不能直接设 DEFAULT 字符串
给 JSON 类型字段设默认值时,不能写成 DEFAULT '{"key": "value"}' —— 这会被当作文本字符串,不是合法 JSON,建表会报错 ERROR 1150 (HY000): Invalid default value for 'data'。
必须用 JSON_OBJECT() 或 CAST() 构造:
ALTER TABLE configs ADD COLUMN data JSON DEFAULT (JSON_OBJECT('status', 'pending'));
注意括号:MySQL 8.0.13+ 支持表达式默认值,必须用 DEFAULT (expr) 形式,括号不能省。
低版本 MySQL(DEFAULT NULL,靠应用层补默认结构。
默认值不是万能补丁,它只在 INSERT 时刻起作用;字段类型、版本兼容性、表达式括号这些细节,漏掉一个就可能让语句失败或行为偏离预期。











