# P32 32. 基础-约束-概述

> 本页是学习笔记，不等同于视频逐字稿。原声字幕未取得（匿名接口字幕轨为空且需登录，未使用任何账号），也没有逐句讲解记录；讲义只按节与页码对应，切点未逐句确证。

> 以同版讲义的公开镜像核对章节与页码（镜像非官方出品）；非逐字稿，示例为原创补充。

## P32 32. 基础-约束-概述

- 原视频：https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=32（p=32），时长 4:30
- 讲义：4.1 约束概述 p61–62（公开镜像；按主题对应，切点 notexact）

- 本集练习数据：practice/p32.sql（先执行，再对照小例）

### 一句话理解

约束是写在表字段上的规则，用来挡住不该进库的数据；它由数据库替你检查。

### 步骤

1. 先分清目的：约束保证数据的正确、有效、完整，而不是替业务做全部判断。
2. 记六类：非空 NOT NULL、唯一 UNIQUE、主键 PRIMARY KEY、默认 DEFAULT、检查 CHECK、外键 FOREIGN KEY。
3. 决定写在哪：建表时直接写在字段后面，或建表后用 ALTER TABLE 补上。
4. 检查版本：CHECK 从 8.0.16 起才真正生效，更早版本会解析但忽略。

### SQL 示例

```
CREATE TABLE practice_score (
  id    INT PRIMARY KEY AUTO_INCREMENT,
  name  VARCHAR(10) NOT NULL UNIQUE,
  score INT CHECK (score >= 0 AND score <= 100),
  level CHAR(1) DEFAULT 'C'
) ENGINE = InnoDB;
```

说明：【原创演示】这是本笔记的原创建表演示，不依赖任何已有表，表名也与视频里的 user 表不同。四列各带一种约束：id 用主键 + 自增，name 非空且唯一，score 用 CHECK 限定 0–100，level 缺省为 'C'。本页原创例已在隔离的 MySQL 8.0.46 测试实例执行通过；你也可以用 p32.sql 在本地练习库跑一遍。

### 易错点

- 以为加了约束业务就安全：跨字段、跨表的规则（如“离职日期不早于入职”）约束管不全，仍需应用层校验。
- 在 8.0.16 之前的版本依赖 CHECK：语句能建成功却不拦数据，必须先确认版本。
- 不写约束名：后续要删除或修改时只能去查自动生成的名字。

### 30 秒速记

六类约束；目的是数据正确 / 有效 / 完整；可建表时写也可 ALTER 补；CHECK 需 8.0.16+。

### 自测

1. 约束能不能替代业务层的全部校验？
   - 答：不能。约束擅长单表单行、可声明的规则；涉及流程、跨表组合、外部系统的规则无法用约束表达，仍要应用逻辑。
2. 为什么示例里显式写 ENGINE=InnoDB？
   - 答：外键等特性依赖支持它的存储引擎，InnoDB 是 MySQL 8.0 默认且支持外键；写清楚可以避免换引擎后约束失效。

### 材料与来源

- [平台视频页] P32 原视频页（BV1Kr4y1i7ru） https://www.bilibili.com/video/BV1Kr4y1i7ru/?p=32
- [官方文档] MySQL 8.0 Reference：CREATE TABLE https://dev.mysql.com/doc/refman/8.0/en/create-table.html

证据说明：按 t30 帧核对：概述页写明“约束是作用于表中字段上的规则，用于限制存储在表中的数据”“目的：保证数据库中数据的正确、有效性和完整性”，并列出六类约束表格，其中 CHECK 标注“8.0.16版本之后”。t012 帧的目录里出现“事务”一词，属课程目录，不作为本集讲解内容。正文示例表为原创，未使用视频里的 user 表；无字幕。
