MySQL和PostgreSQL支持INSERT时省略字段触发DEFAULT,SQLite仅在显式DEFAULT或省略字段时生效;写NULL或空字符串会绕过默认值, STRICT模式下MySQL对无默认NOT NULL列报错,PostgreSQL则要求必须显式定义DEFAULT才可省略。

MySQL 和 PostgreSQL 都支持在 INSERT 时自动使用列的默认值,但行为细节和触发条件不同;SQLite 则只在显式指定 DEFAULT 或省略字段时才生效,不会“自动填充”缺失字段——关键看是否真正省略了该字段。
INSERT 中省略字段 vs 显式写 NULL:行为完全不同
数据库只对「完全不提」的字段应用默认值;一旦写了 NULL 或空字符串,就按字面值插入,哪怕该列定义了 DEFAULT。
-
INSERT INTO users (name) VALUES ('Alice');→age字段若定义了DEFAULT 18,会自动填入18 -
INSERT INTO users (name, age) VALUES ('Alice', NULL);→ 即使age有默认值,也会插入NULL(除非定义了NOT NULL DEFAULT ...) - PostgreSQL 对
NOT NULL列更严格:如果省略且无默认值,直接报错ERROR: null value in column "age" violates not-null constraint
MySQL 的 STRICT 模式决定是否静默补默认值
MySQL 在非 STRICT 模式下,对没有默认值又允许 NULL 的字段会填 NULL;但 STRICT 模式下,若字段既无默认值又不允许 NULL,省略它就会报错 Field 'age' doesn't have a default value。
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
- 检查当前模式:
SELECT @@sql_mode;,含STRICT_TRANS_TABLES或STRICT_ALL_TABLES即为 STRICT - 临时关闭(仅调试用):
SET sql_mode = ''; - 建表时显式声明更可靠:
age INT NOT NULL DEFAULT 18,这样无论模式如何都安全
PostgreSQL 必须显式声明 DEFAULT 才能省略字段
PostgreSQL 不会为未声明 DEFAULT 的字段做任何填充——哪怕它是 NOT NULL。省略字段的前提是它有 DEFAULT 子句(可以是常量、函数如 NOW(),或表达式)。
- 正确示例:
CREATE TABLE logs (id SERIAL, msg TEXT, ts TIMESTAMP DEFAULT NOW());→INSERT INTO logs (msg) VALUES ('start');会自动填入当前时间 - 错误写法:
ts TIMESTAMP NOT NULL但没写DEFAULT→ 省略ts必报错 - 注意:
DEFAULT表达式在每次插入时求值(如NOW()是实时的),不是建表时计算一次
最易被忽略的是:所谓“自动填充”,本质是“省略字段 + 列定义含 DEFAULT + 数据库引擎按规则执行”,三者缺一不可;很多人调了半天发现没生效,其实是 INSERT 语句里悄悄写了 NULL,或者建表时漏了 DEFAULT 关键字。

















