mysql建表时用default设默认值,支持常量和current_timestamp等函数,不支持子查询或表达式;not null字段必须显式定义default,否则插入无值时报错;alter table修改默认值需用modify或drop default。

MySQL 字段默认值怎么设(CREATE TABLE 时)
建表时用 DEFAULT 关键字直接指定,默认值可以是常量、函数(如 CURRENT_TIMESTAMP),但不能是子查询或表达式(如 1+1 或 NOW()+INTERVAL 1 DAY)。
常见写法示例:
CREATE TABLE users ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, status TINYINT DEFAULT 1, created_at DATETIME DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP );
-
DEFAULT 1对数值型字段安全;DEFAULT 'active'对字符串需加引号 -
TIMESTAMP和DATETIME支持CURRENT_TIMESTAMP,但DATETIME在 MySQL 5.6.5+ 才支持带毫秒和ON UPDATE - 如果字段定义了
NOT NULL又没设DEFAULT,插入时没给值会报错:Field 'xxx' doesn't have a default value
ALTER TABLE 添加或修改 DEFAULT 值
已有表加默认值,必须用 ALTER TABLE ... ALTER COLUMN ... SET DEFAULT(MySQL 8.0.13+)或旧语法 MODIFY/CHANGE 配合重定义字段。
推荐方式(兼容性好):
ALTER TABLE users MODIFY status TINYINT DEFAULT 0;
- 用
MODIFY时要重复写出完整字段定义(类型、约束等),否则可能意外丢掉NOT NULL或其他属性 - 想删掉默认值:用
DROP DEFAULT,不是设成DEFAULT NULL(后者仍是默认值,且对NOT NULL字段无效) - 执行后不会影响已有数据,只作用于后续
INSERT未显式赋值的行
NULL 作为默认值是否合法?
是合法的,但行为容易误解。如果字段允许 NULL 且没写 DEFAULT,MySQL 实际隐式按 DEFAULT NULL 处理;但如果显式写 DEFAULT NULL,语义更清晰。
-
name VARCHAR(50) DEFAULT NULL✅ 明确允许空值且默认为空 -
name VARCHAR(50) NOT NULL DEFAULT NULL❌ 冲突,直接报错 -
name VARCHAR(50)→ 等价于DEFAULT NULL(前提是没NOT NULL) - 注意:JSON 类型字段不能设
DEFAULT '',必须用DEFAULT (JSON_OBJECT())或DEFAULT NULL
默认值不生效的几个典型原因
写了 DEFAULT 却发现插入时还是报错或值不对,大概率是这几个点卡住了:
- SQL mode 含
STRICT_TRANS_TABLES或STRICT_ALL_TABLES:此时若字段NOT NULL且无默认值,哪怕插入NULL也会拒绝 - 客户端驱动(如 JDBC)自动把空字符串转成
NULL,而字段又NOT NULL,导致绕过默认值逻辑 - 使用了
INSERT INTO t VALUES ()这种全字段省略写法,但表里有自增主键以外的NOT NULL字段且无默认值,就会失败 - 触发器(
BEFORE INSERT)里主动给字段赋了值,覆盖了默认值
真正麻烦的是混合了严格模式、ORM 自动生成 SQL、以及历史遗留的无默认值 NOT NULL 字段——这种组合下,加默认值只是第一步,还得检查所有写入路径是否真会“用上”它。










