MySQL 默认值使用方法

核心区分两大场景:

  1. 常量默认值 :MySQL5.7 / 8.0 都支持,不用括号
  2. 函数表达式默认值 :仅 MySQL8.0.13+ 支持,必须包一层 ()

特例:CURRENT_TIMESTAMP 8.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';

六、重要限制 & 避坑

  1. 5.7版本限制

    仅允许 CURRENT_TIMESTAMP 作为函数默认值;UUID() / RAND() / DATABASE() 全部不能写DEFAULT。

    5.7如果需要UUID,只能业务代码生成后传入SQL。

  2. 表达式默认不能包含

    子查询、自定义函数、存储过程、引用其他字段的值。

    ❌ col INT DEFAULT (other_col +1) 不支持,不能引用同表其他列。

  3. TEXT/BLOB

    MySQL 8.0才支持默认值,写法:content TEXT DEFAULT ('');5.7 TEXT/BLOB不能设置默认值。

  4. NULL 和 '' 不要混淆

    VARCHAR DEFAULT NULL 和 VARCHAR DEFAULT '' 完全不一样:

    • NULL:未知
    • 空字符串'':有值,是空文本
  5. 主从复制注意

    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;
相关推荐
Nebula_g2 分钟前
云禾外卖补充—项目整体后端运行逻辑-对流程的更深层次理解
java·开发语言·网络·数据库·状态模式·javase
太理摆烂哥6 分钟前
MySQL数据类型
数据库·mysql
程序员小孔.11 分钟前
基于 SpringBoot + UniApp + Vue 的家政服务系统设计与实现
前端·数据库·spring boot·python·docker·微信小程序
执笔为剑19 分钟前
2.1.3-1、兼容MySQL特性-(数据类型、函数、SQL、PL与SQL)
mysql
草莓熊Lotso4 小时前
【C++ 基于微服务的即时通讯系统】etcd + brpc 从安装到服务注册发现全链路实战
网络·数据库·c++·redis·微服务·etcd
Lethehong9 小时前
Oracle 加个字段,目标库就报错?KFS 用“先拆后组“打通异构 DDL
数据库·oracle
Web极客码10 小时前
锁定真正的磁盘卡顿:我用 OpenCode 配合 eBPF 诊断 NVMe 队列深度延迟与 I/O 写放大
数据库·oracle
cspttty10 小时前
2027用户研究求职准备:应用统计学如何补齐研究设计与业务表达
大数据·数据库
roman_日积跬步-终至千里11 小时前
【数据Agent论文·查询与语义|05】Spider:为什么换一个数据库,模型就不会查了?
数据库·数据分析
猫咪很可爱12 小时前
Oracle RAC 启动失败排查:私网通信与内核参数优化实战
运维·数据库·oracle