🗄️ 第四章 管理数据-避免非法数据的功能
📄 一句话概括

NOT NULL 是一道闸门:给列贴上这个标签后,塞 NULL 一律报错——「这列必须有值」从口头约定变成数据库铁律。

📝 本节和前面几节的关系

上一节认清了 NULL 的危害(查不到、统计漏),本节讲第一味解药:关键列直接禁止 NULL。注意 Default(4-7)和 NOT NULL 是搭档不是对手——一个管「没填时补什么」,一个管「根本不许没填」。

一、语法与效果

CREATE TABLE users (
    id    INT PRIMARY KEY,
    name  VARCHAR(20) NOT NULL,     -- 名字必须有
    email VARCHAR(50) NOT NULL      -- 邮箱必须有
);

INSERT INTO users VALUES (1, '张三', '[email protected]');        -- 成功
INSERT INTO users VALUES (2, NULL, '[email protected]');          -- 报错:NOT NULL constraint failed
INSERT INTO users VALUES (2, '李四', NULL);             -- 同样报错

哪行没值哪行炸,错误信息直指列名——脏数据在门口就被扔回去。

二、默认行为:多数列「允许 NULL」

不写 NOT NULL 的列默认允许 NULL(这是历史决定,不是设计推荐)。所以关键业务列必须显式声明 NOT NULL:

列 建议 理由
用户名、邮箱 NOT NULL 没有名字的用户没有意义
手机号 视业务 有些用户真没有
备注、留言 允许 NULL 天然可空
主键 自动 NOT NULL(4-12 细讲) 唯一识别的前提

三、DEFAULT + NOT NULL:黄金搭档

score DECIMAL(5,2) NOT NULL DEFAULT 0

两道闸各司其职:缺省有兜底,显式空无门。

四、动手 Demo:三行三命运

CREATE TABLE t (
    id     INT,
    name   VARCHAR(20) NOT NULL DEFAULT '无名',
    score  DECIMAL(5,2) NOT NULL DEFAULT 0
);

INSERT INTO t (id) VALUES (1);                -- ① 省略 → 默认值顶上,成功
INSERT INTO t (id, name) VALUES (2, '张三');  -- ② 部分省略 → 缺的补默认,成功
INSERT INTO t (id, name, score) VALUES (3, '李四', NULL);  -- ③ 显式 NULL → 报错

③ 的报错正是 NOT NULL 在执法。

五、30 秒实验

给已有数据的表补加 NOT NULL 约束(ALTER TABLE t MODIFY name VARCHAR(20) NOT NULL,MySQL 语法)——如果表里已有 NULL,这条 ALTER 会当场失败:先把存量脏数据清干净,闸门才装得上。

六、常见误区

自测三问 1. 哪些列适合 NOT NULL?(业务上必须有值的:用户名、邮箱;天然可空的备注除外) 2. DEFAULT 和 NOT NULL 怎么配合?(DEFAULT 兜省略,NOT NULL 拦显式空) 3. 给已有 NULL 的表加 NOT NULL 会怎样?(ALTER 失败,要先清存量)

相关笔记