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字段——这种组合下,加默认值只是第一步,还得检查所有写入路径是否真会“用上”它。
