核心区分两大场景:
- 常量默认值 :MySQL5.7 / 8.0 都支持,不用括号
- 函数表达式默认值 :仅 MySQL8.0.13+ 支持,必须包一层
()特例:
CURRENT_TIMESTAMP8.0可以不加括号,也可以写(CURRENT_TIMESTAMP)
一、建表时指定默认值(CREATE TABLE)
1. 常量默认(5.7、8.0通用)
sql
CREATE TABLE t_const_demo (
id INT PRIMARY KEY AUTO_INCREMENT,
age INT DEFAULT 0, -- 数值常量
name VARCHAR(50) DEFAULT '', -- 空字符串
status TINYINT DEFAULT 1, -- 状态默认1
enable BOOLEAN DEFAULT TRUE, -- BOOLEAN底层TINYINT,TRUE=1 FALSE=0
remark VARCHAR(200) DEFAULT NULL -- 默认NULL
);
插入时不写该字段,自动填充默认值:
sql
INSERT INTO t_const_demo(age) VALUES(18);
-- name自动='',status自动=1,enable=1,remark=NULL
2. 函数表达式默认(仅MySQL8.0.13+,必须带括号)
sql
CREATE TABLE t_expr_demo (
id INT PRIMARY KEY AUTO_INCREMENT,
uid CHAR(36) DEFAULT (UUID()),
uid_bin BINARY(16) DEFAULT (UUID_TO_BIN(UUID())),
meta JSON DEFAULT (JSON_ARRAY()),
conn_uid INT DEFAULT (CONNECTION_ID()),
db_name VARCHAR(64) DEFAULT (DATABASE()),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
⚠️ 5.7 执行上面
DEFAULT(UUID())会直接报错!5.7只允许CURRENT_TIMESTAMP这一个函数作为默认值。
二、已有表:修改字段默认值(ALTER TABLE)
语法:ALTER TABLE 表名 MODIFY COLUMN 字段定义;
sql
-- 示例1:给已有字段设置常量默认值
ALTER TABLE t_const_demo
MODIFY COLUMN remark VARCHAR(200) DEFAULT '';
-- 示例2:8.0给字段设置函数默认值
ALTER TABLE t_expr_demo
MODIFY COLUMN uid CHAR(36) DEFAULT (UUID());
注意:ALTER 不会修改表中已经存在的旧数据 ,只对新插入 的记录生效!
旧数据想批量更新需要单独执行 UPDATE。
三、ON UPDATE(时间字段专属,不是DEFAULT)
sql
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
- 新增行:
updated_at填入当前时间 - 更新该行其他字段时,自动刷新
updated_at为最新时间
四、插入语句:如何控制默认值
✅ 方式1:不写该字段,自动使用默认值(最常用)
sql
INSERT INTO t_expr_demo(id) VALUES(NULL);
-- uid、meta、created_at全部自动填充默认值
✅ 方式2:显式写 DEFAULT 关键字,主动使用默认值
sql
INSERT INTO t_expr_demo(id,uid) VALUES(NULL, DEFAULT);
-- uid使用DEFAULT定义的UUID()
✅ 方式3:手动传值,覆盖默认值
sql
INSERT INTO t_expr_demo(id,uid) VALUES(NULL, 'my-custom-uuid');
-- 会使用你传入的值,不再执行默认函数
五、查看表的默认值定义
sql
-- 方法1:查看建表语句
SHOW CREATE TABLE t_expr_demo;
-- 方法2:查询information_schema
SELECT COLUMN_NAME, COLUMN_DEFAULT
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='你的数据库名' AND TABLE_NAME='t_expr_demo';
六、重要限制 & 避坑
-
5.7版本限制
仅允许
CURRENT_TIMESTAMP作为函数默认值;UUID() / RAND() / DATABASE() 全部不能写DEFAULT。5.7如果需要UUID,只能业务代码生成后传入SQL。
-
表达式默认不能包含
子查询、自定义函数、存储过程、引用其他字段的值。
❌
col INT DEFAULT (other_col +1)不支持,不能引用同表其他列。 -
TEXT/BLOB
MySQL 8.0才支持默认值,写法:
content TEXT DEFAULT ('');5.7 TEXT/BLOB不能设置默认值。 -
NULL 和 '' 不要混淆
VARCHAR DEFAULT NULL和VARCHAR DEFAULT ''完全不一样:- NULL:未知
- 空字符串
'':有值,是空文本
-
主从复制注意
UUID()、RAND()、CONNECTION_ID()、CURRENT_USER()这类和会话相关的函数,binlog推荐ROW模式;STATEMENT模式主从数据不一致风险很高。
七、综合完整示例(MySQL8.0)
sql
CREATE TABLE business_table (
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键',
biz_no CHAR(36) DEFAULT (UUID()) COMMENT '业务唯一编号',
status TINYINT DEFAULT 0 COMMENT '状态 0禁用1启用',
amount DECIMAL(12,2) DEFAULT 0.00 COMMENT '金额默认0',
ext_json JSON DEFAULT (JSON_OBJECT()) COMMENT '扩展JSON默认空对象',
create_db VARCHAR(64) DEFAULT (DATABASE()) COMMENT '记录所属库',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;