首页/数据/SQL 速查/默认值、显式 NULL 与 DEFAULT 关键字
变更与事务52 条

默认值、显式 NULL 与 DEFAULT 关键字

省略列取默认值,显式 NULL 存空值:两者语义不同;需要强制取默认值时用 DEFAULT 关键字。

SQL 速查数据更新于 2026-10-13

省略列与显式写空值的区别

插入时「不写这一列」和「写一个空值」是两件事:前者让数据库套用列默认值,后者把空值真的存进去。多数框架把未赋值的字段序列化成显式空值,于是精心设计的默认值被绕过,字段里塞满了空值而没有任何报错。需要强制取默认值时,两种数据库都支持在取值列表里直接写默认值关键字,更新语句的赋值处同样可用。

基本信息

适用平台MySQL 8.0 / PostgreSQL 12 及以上
省略列应用列默认值;无默认值且不允许为空时报错
写空值存入空值;不允许为空的列直接报错
默认值关键字在取值列表或赋值处显式取默认值
严格模式MySQL 8.0 默认开启,写入空值到非空列直接报错

典型使用场景

  • 新建记录只提供部分字段,其余交给默认值
  • 数据修正:把某列改回默认值而不是写成空值
  • 排查字段大面积为空值:确认是不是框架把未赋值字段序列化成了空值
  • 跨版本行为核对:非严格模式下写入空值会被替换成隐式默认值
  • 批量导入时保持默认值语义一致

三种写法与结果

三种写法与结果
-- 省略列:应用列默认值
INSERT INTO t (name) VALUES ('x');

-- 显式空值:列可空时存空值,覆盖默认值
INSERT INTO t (name, status) VALUES ('y', NULL);

-- 强制默认:在取值列表里直接写默认值关键字
INSERT INTO t (name, status) VALUES ('z', DEFAULT);

-- 更新语句里同样可以取默认值
UPDATE t SET status = DEFAULT WHERE id = 1;

-- 确认列的默认值与可空性
-- MySQL:SHOW CREATE TABLE t;
-- PostgreSQL:查询 information_schema.columns

-- 排查空值来源:确认应用是否把未赋值字段序列化成了空值

写法与结果对照

写法结果报错条件
省略列套用列默认值无默认值且不允许为空
写空值存入空值列不允许为空
写默认值关键字套用列默认值该处不支持该语法时
更新为默认值列恢复默认值列没有默认值时写入空值
非严格模式写空值被替换成隐式默认值不报错,行为与严格模式不同
严格模式是老版本与新版本行为差异的分水岭:开的时候写入非法值直接报错,关的时候可能变成截断或隐式替换,数据静默变形。核对历史数据时先确认当时的模式设置。
排查「为什么这一列全是空值」时,先看应用层的序列化逻辑。让对象映射框架跳过未赋值字段,或者在语句里显式写默认值关键字,都比事后补数据干净。

易错点

  • 框架把未赋值字段序列化成显式空值,绕过数据库默认值,字段被填成空值且无报错
  • 在非严格模式下写入空值:被替换成隐式默认值,行为与严格模式完全不同,迁移时数据不一致
  • 更新语句里把列设为空值而不是默认值,业务语义从「恢复默认」变成「清空」
  • 以为写了默认值关键字就能覆盖非空约束:列本身不允许为空且无默认值时依然报错
  • 批量导入工具把缺失字段当成空值写入,与手工插入的结果不一致

数据来源与参考

  • MySQL 8.0 Reference Manual · Data Type Default Values
  • PostgreSQL Documentation · INSERT
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌