MySQL 视频课 · 50 集 / 组

约束:概述、演示、外键与更新删除行为

P32–P36 · 共 5 集 · 每集独立 anchor,可直接从目录跳到本页某一集

视频 p=32 · 时长 4:30

P32 32. 基础-约束-概述

讲义 4.1 约束概述 p61–62

按主题对应,非逐句切分

来源与核对说明

以同版讲义的公开镜像核对章节与页码(镜像非官方出品);非逐字稿,示例为原创补充。

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

讲义索引:p61–62 · 4.1 约束概述 · 切点 notexact

讲义是第三方公开镜像(95 页 PDF),不是官方原件;这里只用它核对章节顺序与页码,不转载正文。

完整来源说明与变更记录 →

看视频,对照阅读:在新标签打开原视频(p=32)

约束这一章从“为什么需要规则”讲起,再列六类约束。

复习模式:快速跳知识点(详解在下方各节)

复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。

一句话理解

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

按这 4 步做

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

小例

先准备本集练习数据:p32.sql · 练习库说明

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+。

自测(2 题,先答再展开)

自测 1:约束能不能替代业务层的全部校验?

不能。约束擅长单表单行、可声明的规则;涉及流程、跨表组合、外部系统的规则无法用约束表达,仍要应用逻辑。

自测 2:为什么示例里显式写 ENGINE=InnoDB?

外键等特性依赖支持它的存储引擎,InnoDB 是 MySQL 8.0 默认且支持外键;写清楚可以避免换引擎后约束失效。

材料与来源

展开材料出处、讲义页码与证据等级
材料类型 / 位置支持了什么
P32 原视频页(BV1Kr4y1i7ru)平台视频页 · P32;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tendt30 为“概述”页:概念、目的、六类约束表。
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. 基础-约束-演示

讲义 4.2 约束演示 p62–64

按主题对应,非逐句切分

来源与核对说明

以同版讲义的公开镜像核对章节与页码(镜像非官方出品);非逐字稿,示例为原创补充。

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

讲义索引:p62–64 · 4.2 约束演示 · 切点 notexact

讲义是第三方公开镜像(95 页 PDF),不是官方原件;这里只用它核对章节顺序与页码,不转载正文。

完整来源说明与变更记录 →

看视频,对照阅读:在新标签打开原视频(p=33)

约束演示:故意插坏数据,看 1062 / 1048 / 3819 三种报错。

复习模式:快速跳知识点(详解在下方各节)

复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。

一句话理解

这一集把常用约束写进一张表(主键、非空、唯一、默认、CHECK;外键在 P34 单独讲),再故意插入坏数据,看数据库怎样拒绝。

按这 4 步做

  1. 先建带约束的表:主键自增、姓名非空且唯一、年龄用 CHECK 限定范围、状态给默认值。
  2. 先插合法数据,确认能进;再一次只违反一条规则,观察报错。
  3. 对着错误码读原因:1062 是唯一冲突、1048 是非空、3819 是 CHECK 不通过。
  4. 改回合法值再插一次,确认表仍可正常写入。

小例

先准备本集练习数据:p33.sql · 练习库说明

SQL 示例
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 秒速记

建表带约束 → 插合法数据 → 逐条违反 → 读 1062/1048/3819;UNIQUE 允许多 NULL;自增不回填。

自测(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/tendt20/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. 基础-约束-外键约束

讲义 4.3.1 外键介绍 / 4.3.2 外键语法 p64–66

按主题对应,非逐句切分

来源与核对说明

以同版讲义的公开镜像核对章节与页码(镜像非官方出品);非逐字稿,示例为原创补充。

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

讲义索引:p64–66 · 4.3.1 外键介绍 / 4.3.2 外键语法 · 切点 notexact

讲义是第三方公开镜像(95 页 PDF),不是官方原件;这里只用它核对章节顺序与页码,不转载正文。

完整来源说明与变更记录 →

看视频,对照阅读:在新标签打开原视频(p=34) · 先看跟播对照

外键是约束里最需要理解关系的一个:子表引用父表的唯一值。

复习模式:快速跳知识点(详解在下方各节)

复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。

一句话理解

外键让子表的一列只能取父表里真实存在的值,从而不让“孤儿数据”进库。

按这 4 步做

  1. 确定方向:employee.dept_id 指向 department.id,employee 是子表,department 是父表。没有外键时直接删父表一行,子表会留下指向不存在部门的孤儿数据,而且不报错——外键就是用来挡这个的。
  2. 确认父表被引用的列有唯一索引(通常是主键),两边数据类型一致。
  3. 建表时写 FOREIGN KEY (dept_id) REFERENCES department(id),或建表后用 ALTER TABLE 补。
  4. 插入一个父表不存在的 dept_id,确认被拒绝(错误 1452)。

小例

先准备本集练习数据:p34.sql · 练习库说明

SQL 示例
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 秒速记

子表引用父表唯一列;类型要一致;可建表时写也可 ALTER 补;NULL 不检查;违反报 1452。

自测(2 题,先答再展开)

自测 1:为什么 department.id 必须是主键或唯一索引?

外键要确认子表的值能唯一对应父表的一行;父表被引用列不唯一时无法判断指向哪条记录,数据库会直接拒绝建约束。

自测 2:小李 dept_id 为 NULL,加外键后会被删掉吗?

不会。外键只校验非 NULL 的引用值,NULL 表示“没有引用”,可以存在于子表。

材料与来源

展开材料出处、讲义页码与证据等级
材料类型 / 位置支持了什么
P34 原视频页(BV1Kr4y1i7ru)平台视频页 · P34;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tendt012/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. 基础-约束-外键删除更新行为

讲义 4.3.3 删除/更新行为 p67–68

按主题对应,非逐句切分

来源与核对说明

以同版讲义的公开镜像核对章节与页码(镜像非官方出品);非逐字稿,示例为原创补充。

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

讲义索引:p67–68 · 4.3.3 删除/更新行为 · 切点 notexact

讲义是第三方公开镜像(95 页 PDF),不是官方原件;这里只用它核对章节顺序与页码,不转载正文。

完整来源说明与变更记录 →

看视频,对照阅读:在新标签打开原视频(p=35)

父表被删被改时子表如何反应,由删除/更新行为决定。

复习模式:快速跳知识点(详解在下方各节)

复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。

一句话理解

父表记录被删或被改时子表怎么办,由 ON DELETE / ON UPDATE 后面的行为决定。

按这 4 步做

  1. RESTRICT / NO ACTION:子表还有引用就拒绝删除或修改,这是默认的保守选择。
  2. CASCADE:父表删一行,子表对应的行一起删;父表改主键,子表跟着改。
  3. SET NULL:父表删一行,子表外键列置空,前提是该列允许 NULL。
  4. SET DEFAULT:设计上置默认值,但 InnoDB 不支持,别在 MySQL 里指望它。

小例

先准备本集练习数据:p35.sql · 练习库说明

SQL 示例
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 秒速记

RESTRICT/NO ACTION 拒绝、CASCADE 连动、SET NULL 置空(列须可空)、SET DEFAULT InnoDB 不支持。

自测(2 题,先答再展开)

自测 1:SET NULL 和 CASCADE 在“删部门”时分别发生什么?

SET NULL 只把子表外键置空、员工行保留;CASCADE 会把引用该部门的员工行一起删掉,数据直接消失。

自测 2:为什么 RESTRICT 常被当作默认推荐?

它让删除在存在引用时失败,迫使你先处理子数据,避免一次误删扩散到多张表。

材料与来源

展开材料出处、讲义页码与证据等级
材料类型 / 位置支持了什么
P35 原视频页(BV1Kr4y1i7ru)平台视频页 · P35;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tendt020–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. 基础-约束-小结

讲义:参照前节整理,无独立讲义正文

覆盖范围:4.1–4.3 约束(p61–68)(不设本集切点)

来源与核对说明

以同版讲义的公开镜像核对章节与页码(镜像非官方出品);非逐字稿,示例为原创补充。

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

讲义索引:无本集正文 · 切点 none

讲义是第三方公开镜像(95 页 PDF),不是官方原件;这里只用它核对章节顺序与页码,不转载正文。

完整来源说明与变更记录 →

看视频,对照阅读:在新标签打开原视频(p=36)

约束收尾:六类约束一页清单,以及它们管什么。

这一集在讲什么

约束小结就是六类约束的清单,加上“它保证什么、不能保证什么”。

要点(3 条)

  1. 六类:NOT NULL、UNIQUE、PRIMARY KEY(可配 AUTO_INCREMENT)、DEFAULT、CHECK、FOREIGN KEY。
  2. 各自管什么:空值、重复、唯一标识、缺省值、取值范围、表间引用;主键 = 唯一 + 非空,UNIQUE 允许多个 NULL。
  3. 怎么加:建表时写在字段后,或用 ALTER TABLE 补;已有脏数据要先清洗,否则 ALTER 直接失败。

30 秒回忆

六类约束 + 各自作用 + 加法(建表 / ALTER)+ 先洗数据;主键 = 唯一 + 非空。

想再练一下(1 题,选做)

自测 1:UNIQUE 和 PRIMARY KEY 最主要的区别是什么?

主键要求非空且唯一,一张表只能有一个;UNIQUE 只保证不重复,允许 NULL,一张表可以有多个唯一约束。

材料与来源

展开材料出处、讲义页码与证据等级
材料类型 / 位置支持了什么
P36 原视频页(BV1Kr4y1i7ru)平台视频页 · P36;采样静帧 t012/t20/t30/t40/t50/t60/t70/t80/tendt80/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(只用于确认画面主题,不作内容边界)
  • 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号

等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。