MySQL 视频课 · 50 集 / 组
约束:概述、演示、外键与更新删除行为
P32–P36 · 共 5 集 · 每集独立 anchor,可直接从目录跳到本页某一集
视频 p=32 · 时长 4:30
P32 32. 基础-约束-概述
原视频:在 B 站新标签打开(p=32) · 单独打开这一集 →
看视频,对照阅读:在新标签打开原视频(p=32)
约束这一章从“为什么需要规则”讲起,再列六类约束。
复习模式:快速跳知识点(详解在下方各节)
复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。
一句话理解
约束是写在表字段上的规则,用来挡住不该进库的数据;它由数据库替你检查。
按这 4 步做
- 先分清目的:约束保证数据的正确、有效、完整,而不是替业务做全部判断。
- 记六类:非空 NOT NULL、唯一 UNIQUE、主键 PRIMARY KEY、默认 DEFAULT、检查 CHECK、外键 FOREIGN KEY。
- 决定写在哪:建表时直接写在字段后面,或建表后用 ALTER TABLE 补上。
- 检查版本:CHECK 从 8.0.16 起才真正生效,更早版本会解析但忽略。
小例
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 秒速记
自测(2 题,先答再展开)
自测 1:约束能不能替代业务层的全部校验?
不能。约束擅长单表单行、可声明的规则;涉及流程、跨表组合、外部系统的规则无法用约束表达,仍要应用逻辑。
自测 2:为什么示例里显式写 ENGINE=InnoDB?
外键等特性依赖支持它的存储引擎,InnoDB 是 MySQL 8.0 默认且支持外键;写清楚可以避免换引擎后约束失效。
材料与来源
展开材料出处、讲义页码与证据等级
| 材料 | 类型 / 位置 | 支持了什么 |
|---|---|---|
| P32 原视频页(BV1Kr4y1i7ru) | 平台视频页 · P32;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tend | t30 为“概述”页:概念、目的、六类约束表。 |
| MySQL 8.0 Reference:CREATE TABLE | 官方文档 | 核对约束写法与 CHECK 的版本要求,未逐字引用。 |
按 t30 帧核对:概述页写明“约束是作用于表中字段上的规则,用于限制存储在表中的数据”“目的:保证数据库中数据的正确、有效性和完整性”,并列出六类约束表格,其中 CHECK 标注“8.0.16版本之后”。t012 帧的目录里出现“事务”一词,属课程目录,不作为本集讲解内容。正文示例表为原创,未使用视频里的 user 表;无字幕。
讲义对照:讲义 4.1 约束概述 · p61–62(公开镜像;按主题对应,切点 notexact)
- 画面静帧 9 帧,采样点 0:12–4:17 / 全片 4:30(只用于确认画面主题,不作内容边界)
- 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号
等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。
视频 p=33 · 时长 15:00
P33 33. 基础-约束-演示
原视频:在 B 站新标签打开(p=33) · 单独打开这一集 →
看视频,对照阅读:在新标签打开原视频(p=33)
约束演示:故意插坏数据,看 1062 / 1048 / 3819 三种报错。
复习模式:快速跳知识点(详解在下方各节)
复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。
一句话理解
这一集把常用约束写进一张表(主键、非空、唯一、默认、CHECK;外键在 P34 单独讲),再故意插入坏数据,看数据库怎样拒绝。
按这 4 步做
- 先建带约束的表:主键自增、姓名非空且唯一、年龄用 CHECK 限定范围、状态给默认值。
- 先插合法数据,确认能进;再一次只违反一条规则,观察报错。
- 对着错误码读原因:1062 是唯一冲突、1048 是非空、3819 是 CHECK 不通过。
- 改回合法值再插一次,确认表仍可正常写入。
小例
CREATE TABLE practice_user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(10) NOT NULL UNIQUE,
age INT CHECK (age > 0 AND age <= 120),
status CHAR(1) DEFAULT '1'
) ENGINE = InnoDB;
INSERT INTO practice_user (name, age) VALUES ('小甲', 19), ('小乙', 25);
【原创演示】原创演示表,字段与视频里的 user 表相似,但表名和数据都不同。插入只给 name 和 age,id 由自增生成,status 取默认 '1'。下面三种插入应被拒绝:重复 name 报 1062 Duplicate entry;name 传 NULL 报 1048;age 传 130 报 3819 检查约束失败。这些结果已在隔离的 MySQL 8.0.46 测试实例逐条验证(1062/1048/3819);你也可以用 p33.sql 在本地练习库复现。
易错点
- 以为 UNIQUE 只能有一个 NULL:唯一约束允许多行 NULL,因为 NULL 之间不算相等。
- 以为自增编号会回填:删掉最大 id 再插新行,编号继续往后走,不补空位。
- 以为 CHECK 会顺带拦住 NULL:表达式结果为未知时按通过处理,要连 NULL 一起挡就得再写 IS NOT NULL。
30 秒速记
自测(2 题,先答再展开)
自测 1:为什么重复插入同名会失败,而插入两个 NULL 姓名不会?
name 同时有 NOT NULL 和 UNIQUE:NULL 先被 NOT NULL 挡住;如果只有 UNIQUE,多个 NULL 是被允许的,因为唯一性比较不把 NULL 当作相等。
自测 2:报 3819 说明什么?
CHECK 的表达式对这条数据不成立(结果为假),数据库拒绝了写入;先看表达式范围和传入值。
材料与来源
展开材料出处、讲义页码与证据等级
| 材料 | 类型 / 位置 | 支持了什么 |
|---|---|---|
| P33 原视频页(BV1Kr4y1i7ru) | 平台视频页 · P33;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tend | t20/tend 为“根据需求,完成表结构的创建”页,t70 为建表+插入演示。 |
| MySQL 8.0 Reference:CREATE TABLE | 官方文档 | 核对约束语法与自增、默认值行为,未逐字引用。 |
按 t70 帧核对:画面是 Workbench 里执行建表 + 插入的演示,建表含主键自增、name 非空唯一、age 的 CHECK 范围、status 默认值,输出区出现 1062 Duplicate entry 报错。正文改用原创表名 practice_user 与自造数据,未照抄课堂表结构与姓名;无字幕,讲师逐步解说未核实。
讲义对照:讲义 4.2 约束演示 · p62–64(公开镜像;按主题对应,切点 notexact)
- 画面静帧 9 帧,采样点 0:12–14:47 / 全片 15:00(只用于确认画面主题,不作内容边界)
- 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号
等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。
视频 p=34 · 时长 10:14
P34 34. 基础-约束-外键约束
原视频:在 B 站新标签打开(p=34) · 单独打开这一集 →
看视频,对照阅读:在新标签打开原视频(p=34) · 先看跟播对照
外键是约束里最需要理解关系的一个:子表引用父表的唯一值。
复习模式:快速跳知识点(详解在下方各节)
复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。
一句话理解
外键让子表的一列只能取父表里真实存在的值,从而不让“孤儿数据”进库。
跟播:视频里 ↔ 本站
视频用 emp(子表)与 dept(父表)讲外键,并说明这两张表在数据库层面其实没建约束。
| 视频里 / 原课字段 | 本站对应 |
|---|---|
| 讲义 dept:1 研发部、2 市场部(p65 原名) | 本页练习表同样用 1 研发部、2 市场部(沿用讲义原名) |
| 讲义 emp 6 行、含 job / entrydate | 本站 employee 4 行、5 列(没有 job / entrydate) |
看完应能:能说出子表父表方向,并知道插入不存在的父键会报 1452
P37 起换成本站另一套 6 列小表(2 号部门叫测试部),那是那一页的练习数据,不是这里写错。
按这 4 步做
- 确定方向:employee.dept_id 指向 department.id,employee 是子表,department 是父表。没有外键时直接删父表一行,子表会留下指向不存在部门的孤儿数据,而且不报错——外键就是用来挡这个的。
- 确认父表被引用的列有唯一索引(通常是主键),两边数据类型一致。
- 建表时写 FOREIGN KEY (dept_id) REFERENCES department(id),或建表后用 ALTER TABLE 补。
- 插入一个父表不存在的 dept_id,确认被拒绝(错误 1452)。
小例
ALTER TABLE employee
ADD CONSTRAINT fk_employee_department
FOREIGN KEY (dept_id) REFERENCES department (id);
【原创演示】依赖两张练习表:department(id,name) 有 (1,'研发部')、(2,'市场部');employee 就是前面那四行。加约束后,小林、小周、小陈的 dept_id 都能在父表找到;小李的 dept_id 是 NULL,外键不检查 NULL,所以也能留下。再插 dept_id=99 会报 1452 无法添加或更新子行。本页原创例已在隔离的 MySQL 8.0.46 测试实例执行通过(含被 1452 拒绝的那次插入);也可以用 p34.sql 复现。
易错点
- 父表被引用列没有唯一索引:建外键直接失败(错误 1822),这不是数据问题而是索引问题。
- 子表里已经有对不上父表的旧数据:先加约束会失败,必须先清脏数据或补父表记录。
- 以为外键能挡所有错误值:NULL 不受外键检查,允许空就等于允许“没有部门”的行。
30 秒速记
自测(2 题,先答再展开)
自测 1:为什么 department.id 必须是主键或唯一索引?
外键要确认子表的值能唯一对应父表的一行;父表被引用列不唯一时无法判断指向哪条记录,数据库会直接拒绝建约束。
自测 2:小李 dept_id 为 NULL,加外键后会被删掉吗?
不会。外键只校验非 NULL 的引用值,NULL 表示“没有引用”,可以存在于子表。
材料与来源
展开材料出处、讲义页码与证据等级
| 材料 | 类型 / 位置 | 支持了什么 |
|---|---|---|
| P34 原视频页(BV1Kr4y1i7ru) | 平台视频页 · P34;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tend | t012/t020 为外键概念页与 emp/dept 示意图。 |
| MySQL 8.0 Reference:FOREIGN KEY 约束 | 官方文档 | 核对父表唯一索引与 1452/1822 的触发条件,未逐字引用。 |
按 t012/t020 帧核对:外键页给出概念“外键用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性”,并用 emp(子表,dept_id)与 dept(父表,id)示意,页面明确注明“两张表在数据库层面并未建立外键关联”。正文沿用这个父子关系,但使用自己的练习表与数据,未声称与课堂 emp 表一致;无字幕。
讲义对照:讲义 4.3.1 外键介绍 / 4.3.2 外键语法 · p64–66(公开镜像;按主题对应,切点 notexact)
- 画面静帧 9 帧,采样点 0:12–10:01 / 全片 10:14(只用于确认画面主题,不作内容边界)
- 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号
等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。
视频 p=35 · 时长 8:58
P35 35. 基础-约束-外键删除更新行为
原视频:在 B 站新标签打开(p=35) · 单独打开这一集 →
看视频,对照阅读:在新标签打开原视频(p=35)
父表被删被改时子表如何反应,由删除/更新行为决定。
复习模式:快速跳知识点(详解在下方各节)
复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。
一句话理解
父表记录被删或被改时子表怎么办,由 ON DELETE / ON UPDATE 后面的行为决定。
按这 4 步做
- RESTRICT / NO ACTION:子表还有引用就拒绝删除或修改,这是默认的保守选择。
- CASCADE:父表删一行,子表对应的行一起删;父表改主键,子表跟着改。
- SET NULL:父表删一行,子表外键列置空,前提是该列允许 NULL。
- SET DEFAULT:设计上置默认值,但 InnoDB 不支持,别在 MySQL 里指望它。
小例
ALTER TABLE employee
ADD CONSTRAINT fk_employee_department
FOREIGN KEY (dept_id) REFERENCES department (id)
ON DELETE SET NULL
ON UPDATE CASCADE;
【原创演示】仍是那两张练习表。设成 SET NULL 后删掉部门 2,小陈这一行的 dept_id 会变成 NULL,人还留在表里;如果改成 ON DELETE CASCADE,删部门 2 会连小陈一起删掉,这就是风险点。dept_id 必须可为空,否则 SET NULL 在删除时会报错。本页原创例已在隔离的 MySQL 8.0.46 测试实例执行通过;也可以用 p35.sql 复现。
易错点
- 为了“删起来方便”选 CASCADE:删一条父表记录可能连带删掉大量子表业务数据,且难恢复。
- 外键列是 NOT NULL 却设 SET NULL:删除父行时直接报错,约束和列定义要先对齐。
- 以为 RESTRICT 和 CASCADE 只是写法不同:一个拒绝操作、一个扩散删除,语义正好相反。
30 秒速记
自测(2 题,先答再展开)
自测 1:SET NULL 和 CASCADE 在“删部门”时分别发生什么?
SET NULL 只把子表外键置空、员工行保留;CASCADE 会把引用该部门的员工行一起删掉,数据直接消失。
自测 2:为什么 RESTRICT 常被当作默认推荐?
它让删除在存在引用时失败,迫使你先处理子数据,避免一次误删扩散到多张表。
材料与来源
展开材料出处、讲义页码与证据等级
| 材料 | 类型 / 位置 | 支持了什么 |
|---|---|---|
| P35 原视频页(BV1Kr4y1i7ru) | 平台视频页 · P35;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tend | t020–t040 为“外键约束 删除/更新行为”表格页。 |
| MySQL 8.0 Reference:FOREIGN KEY 约束的参照操作 | 官方文档 | 核对 CASCADE/SET NULL/RESTRICT 与 InnoDB 对 SET DEFAULT 的支持情况,未逐字引用。 |
按 t020/t030/t040/t070 帧核对:画面为“外键约束 删除/更新行为”表格,列出 NO ACTION(与 RESTRICT 一致)、RESTRICT、CASCADE、SET NULL(要求外键允许取 null)、SET DEFAULT(Innodb 不支持)。正文示例 DDL 为原创且未执行;无字幕,讲师现场演示未核实。
讲义对照:讲义 4.3.3 删除/更新行为 · p67–68(公开镜像;按主题对应,切点 notexact)
- 画面静帧 9 帧,采样点 0:12–8:45 / 全片 8:58(只用于确认画面主题,不作内容边界)
- 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号
等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。
视频 p=36 · 时长 2:15
P36 36. 基础-约束-小结
原视频:在 B 站新标签打开(p=36) · 单独打开这一集 →
看视频,对照阅读:在新标签打开原视频(p=36)
约束收尾:六类约束一页清单,以及它们管什么。
这一集在讲什么
约束小结就是六类约束的清单,加上“它保证什么、不能保证什么”。
要点(3 条)
- 六类:NOT NULL、UNIQUE、PRIMARY KEY(可配 AUTO_INCREMENT)、DEFAULT、CHECK、FOREIGN KEY。
- 各自管什么:空值、重复、唯一标识、缺省值、取值范围、表间引用;主键 = 唯一 + 非空,UNIQUE 允许多个 NULL。
- 怎么加:建表时写在字段后,或用
ALTER TABLE补;已有脏数据要先清洗,否则 ALTER 直接失败。
30 秒回忆
想再练一下(1 题,选做)
自测 1:UNIQUE 和 PRIMARY KEY 最主要的区别是什么?
主键要求非空且唯一,一张表只能有一个;UNIQUE 只保证不重复,允许 NULL,一张表可以有多个唯一约束。
材料与来源
展开材料出处、讲义页码与证据等级
| 材料 | 类型 / 位置 | 支持了什么 |
|---|---|---|
| P36 原视频页(BV1Kr4y1i7ru) | 平台视频页 · P36;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tend | t80/tend 为六类约束小结页。 |
| MySQL 8.0 Reference:CREATE TABLE 与约束 | 官方文档 | 核对六类约束关键字,未逐字引用。 |
讲义无“小结”正文;本页参照前节 4.1–4.3 约束(p61–68)整理。画面 t80/tend 帧完整列出六类约束;原声字幕未取得,讲师逐句讲解未核。
讲义对照:参照前节整理,无独立讲义正文;参照前节 4.1–4.3 约束(p61–68)
- 画面静帧 9 帧,采样点 0:12–2:02 / 全片 2:15(只用于确认画面主题,不作内容边界)
- 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号
等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。