📄 一句话概括
约束是比类型更进一步的防线:类型只管「你是什么」(是数字还是文字),约束管「你合不合规」(能不能为空、能不能重复、超没超范围)——从本节到 4-13,一章的剩余篇幅全在讲各种约束。
📝 本节和前面几节的关系
4-1~4-5 的类型是第一道防线,但刚才 4-5 也看到了它的软肋:塞 2 进 BOOLEAN 列照样收。本节引出第二道防线——约束,并给全章画出总图:4-7~4-13 逐个登场,4-14~4-17 的事务是另一路「保证处理不出错」的手段。
一、两道防线的分工
| 防线 | 管什么 | 例子 |
|---|---|---|
| 类型(4-1~4-5) | 你是什么 | score 必须是数字 |
| 约束(本节起) | 你合不合规 | score 不能为空、不能重复、必须在 0~100 |
二、本章约束总图
建表时给列加上各种「附加条件」,每个条件就是一种约束:
列级约束(管一个列)
├─ DEFAULT 默认值 → 4-7
├─ NULL / NOT NULL 允许空 / 禁止空 → 4-8、4-9
├─ UNIQUE 不许重复 → 4-10
├─ AUTO_INCREMENT 自动编号 → 4-11
└─ PRIMARY KEY 主键 → 4-12
表级约束(管表与表)
└─ FOREIGN KEY 外键 → 4-13
三、约束写在建表语句里
CREATE TABLE students (
id INT PRIMARY KEY, -- 主键:唯一 + 不许空
name VARCHAR(20) NOT NULL, -- 不许空
email VARCHAR(50) UNIQUE, -- 不许重复
score DECIMAL(5,2) DEFAULT 0 -- 不填就给 0
);
约束写在建表那一刻,之后每一次 INSERT/UPDATE 都会被检查——数据库不知疲倦,帮人守一辈子。
四、为什么要这么多约束
类型之外的「非法数据」多得很:
- 忘填邮箱(空值)
- 两个用户占了同一个邮箱(重复)
- 余额被改成负数(超范围)
软件的问题大多出在「脏数据」进库的那一刻。约束让错误在最入口处爆炸,而不是半夜三更让报表炸出天文数字。
五、动手 Demo:约束真的会拦
CREATE TABLE t (
email VARCHAR(50) UNIQUE
);
INSERT INTO t VALUES ('[email protected]'); -- 第一次:成功
INSERT INTO t VALUES ('[email protected]'); -- 第二次:报错 UNIQUE constraint failed
重复值第二次插入当场被拒——这就是约束和类型的差别:它知道你上一次存了什么。
六、30 秒实验
在上一张表基础上加一列 score DECIMAL(5,2) DEFAULT 0,执行 INSERT INTO t (email) VALUES ('[email protected]') 后查询——score 自动是 0(DEFAULT 在 4-7 细讲)。
七、常见误区
- 「约束让插入变慢,尽量不加」:约束检查的开销微乎其微,而脏数据造成的返工代价巨大;先保证对,再谈快
- 「约束只在建表时管一次」:它管每一次写入,从建表到删表,一次不落
自测三问
1. 类型和约束各管什么?(类型管是什么;约束管合不合规) 2. 本章的七个约束分别是什么?(DEFAULT、NULL/NOT NULL、UNIQUE、AUTO_INCREMENT、PRIMARY KEY、FOREIGN KEY) 3. 为什么错误要在入口处爆炸?(脏数据越晚发现,返工代价越大)- ☐ 下一节(4-7 DEFAULT-设置默认值)
相关笔记
- BOOLEAN-仅处理两种值的数据类型 —— 上一节:类型拦不住 2 的软肋
- DEFAULT-设置默认值 —— 下一节:第一个具体约束
- 🗄️ 数据库基础 · 索引 —— 全课路线图