mysql中default设置需严格遵循类型规则:字符串加单引号,数值不加引号,current_timestamp不带括号;text/blob在8.0.19前不支持默认值;alter语法因版本而异;default仅对insert生效,update需显式set col = default。

CREATE TABLE 时设置 DEFAULT 必须带引号、函数不加括号
字符串类型默认值必须用单引号包裹,DEFAULT active会报错,正确写法是DEFAULT 'active';数值类型直接写数字,DEFAULT '0'可能触发隐式转换;时间类型推荐CURRENT_TIMESTAMP,但CURRENT_TIMESTAMP()非法——括号不能加。
NOT NULL 字段若没设 DEFAULT,且 SQL mode 启用了 STRICT_TRANS_TABLES,INSERT 时省略该字段必报错:Field 'xxx' doesn't have a default value。TEXT/BLOB 类型在 MySQL 8.0.19 之前不支持 DEFAULT,哪怕写 DEFAULT '' 也会被拒绝。
ALTER TABLE 修改默认值要看 MySQL 版本选语法
MySQL 8.0.13+ 推荐用 ALTER COLUMN ... SET DEFAULT,安全、语义清晰:
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'inactive';
旧版本(如 5.7)必须用 MODIFY COLUMN,但它会重定义整列,容易漏掉约束:
- 必须完整写出类型和原有约束,比如原字段是
VARCHAR(20) NOT NULL,MODIFY COLUMN status VARCHAR(20) DEFAULT 'inactive'会悄悄删掉NOT NULL - 想删默认值,用
DROP DEFAULT,不是DEFAULT NULL——后者仍是默认值,且与NOT NULL冲突
INSERT 时 DEFAULT 不生效的三个典型原因
写了 DEFAULT 却没生效,大概率是这些点被绕过了:
- 客户端驱动(如 PyMySQL、JDBC)把空字符串
''自动转成NULL,而字段又是NOT NULL,直接报错,根本没走到默认值逻辑 -
SQL mode含STRICT_ALL_TABLES时,即使字段允许NULL,显式插入NULL也会被拒绝,不会退而使用默认值 - 误以为
UPDATE会触发默认值——不会。DEFAULT只对INSERT生效;UPDATE SET col = DEFAULT才强制重置为默认值
CURRENT_TIMESTAMP 作为默认值要卡版本和类型
DATETIME 字段用 CURRENT_TIMESTAMP 作默认值,要求 MySQL ≥ 5.6.5;ON UPDATE 子句则要 ≥ 8.0.19。TIMESTAMP 天然支持,且存 UTC、读本地时区;DATETIME 存字面值、无时区转换。
给已有字段加 CURRENT_TIMESTAMP 默认值失败?先查 SELECT @@sql_mode,确认是否含 NO_ZERO_DATE —— 如果表里已有 '0000-00-00 00:00:00' 这类非法时间,ALTER 就会报 Invalid default value for 'ts'。清理脏数据或临时调低 SQL mode(仅调试),比硬改语法更靠谱。
默认值只影响后续 INSERT,已有数据一动不动。别指望它“修复”历史记录。











