MySQL 视频课 · 50 集 / 多表查询:多表关系、内/外/自连接、联合查询 / P37
第 37 集 / 共 50 · 多表查询:多表关系、内/外/自连接、联合查询 · 视频 p=37 · 时长 12:12
P37 37. 基础-多表查询-多表关系介绍
看视频,对照阅读:在新标签打开原视频(p=37) · 先看跟播对照
先讲清数据:本页用两张小表——department(1 研发部、2 测试部、3 运营部)与 employee 四行(小林 22/研发/8000/上级 2,小周 25/研发/10000/无上级,小陈 30/测试/12000/上级 2,小李 21/无部门/NULL/上级 2)。讲义这一节用的是 emp 17 行 / dept 6 行,2 号部门叫市场部;表名、行数、部门名都不同,结构对应即可,不要对总数。
复习模式:快速跳知识点(详解在下方各节)
复习顺序:先看“一句话理解”能否复述,再扫步骤,最后做自测;答不出时回到小例与易错。
一句话理解
表之间的关系就三种:一对一、一对多、多对多。判断方法很实在——看外键放在哪张表、要不要第三张中间表。
跟播:视频里 ↔ 本站
视频用 emp / dept 讲一对多、多对多、一对一三种关系,重点是外键放哪张表。
| 视频里 / 原课字段 | 本站对应 |
|---|---|
| 讲义 emp 17 行、8 列(含 job / entrydate / managerid) | 本站 employee 4 行、6 列(含 manager_id,没有 job / entrydate) |
| 讲义 dept 6 行:1 研发部、2 市场部、3 财务部… | 本站 department 3 行:1 研发部、2 测试部、3 运营部(2 号名字不同) |
看完应能:看到「一个部门多个员工」能立刻说出外键放 employee 这一侧
看视频时以讲义 emp/dept 为准,跟练时用本站 employee/department;表名与数字都不同,结构对应即可。
按这 4 步做
- 先数“谁多”。一个部门有多名员工,一名员工只属于一个部门,所以 employee 是“多”的一方,外键 dept_id 放这里。为什么:外键放多的一方,每条员工记录只能填一个部门号,重复是天然的。
- 一对一用于拆表。比如员工表和员工档案表,两边都只对应一条;外键放任意一方,但要加 UNIQUE,否则会退化成一堆一对多。
- 多对多必须建中间表。学生选课,一个学生选多门课,一门课被多人选;中间表放 student_id、course_id 两个外键,联合起来当主键,重复选课才插不进去。
- 关系定完再写查询。一对多靠 dept_id = id 连两张表;多对多要连三张表;一对一多一次 join。连接条件不是猜的,是外键指出来的。
小例
-- 本页练习用的建表段:在 mysqlnotes_p37 里执行一次(后面各页用各自的 pNN.sql,不复用这里)
-- department(1 研发部, 2 测试部, 3 运营部)
-- employee:小林22/研发8000/上级2,小周25/研发10000/无上级,小陈30/测试12000/上级2,小李21/无部门/NULL/上级2
CREATE TABLE department (
id INT PRIMARY KEY,
name VARCHAR(20) NOT NULL
);
CREATE TABLE employee (
id INT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age INT,
dept_id INT,
salary INT,
manager_id INT
);
INSERT INTO department VALUES (1,'研发部'),(2,'测试部'),(3,'运营部');
INSERT INTO employee VALUES
(1,'小林',22,1,8000,2),
(2,'小周',25,1,10000,NULL),
(3,'小陈',30,2,12000,2),
(4,'小李',21,NULL,NULL,2);
-- 一对多:外键放在“多”的一方
ALTER TABLE employee
ADD CONSTRAINT fk_emp_dept
FOREIGN KEY (dept_id) REFERENCES department(id);
前面几段只建表灌数据;这两张表属于本页练习库 mysqlnotes_p37,后面各页用的是各自的 pNN.sql,列数和数据类型可能不同,别拿这里的 6 列结构去套别的页。最后一段给 employee.dept_id 加外键:以后 dept_id 只能填 1、2、3 或 NULL,写 99 会被拒绝。自检跑 SELECT id,name,dept_id FROM employee ORDER BY id,应得 4 行,小李的 dept_id 是 NULL——外键允许空值,不代表他有部门。
易错点
- 外键方向写反(在 department 里放 employee_id),一个部门只能记一个员工,一对多就装不下了。
- 多对多只在一边加外键,另一边的对应关系无处存放,迟早出现重复行。
- 外键列类型必须和被引用主键一致(INT 对 INT),类型不同建约束会失败。
30 秒速记
自测(2 题,先答再展开)
自测 1:一个部门多名员工,外键该放哪张表?
employee(多的一方),存 dept_id 指向 department.id;放反了一个部门只能挂一个员工。
自测 2:多对多的中间表为什么常把两个外键做成联合主键?
防止同一对组合重复插入,同时天然形成“两个一对多”。
材料与来源
展开材料出处、讲义页码与证据等级
| 材料 | 类型 / 位置 | 支持了什么 |
|---|---|---|
| BV1Kr4y1i7ru P37(平台标题) | 平台视频页 · P37 | 静帧 t=292s 显示“学生-课程”多对多与中间表两个外键;t=219s 为本节标题页 |
| MySQL 8.0 Reference Manual — JOIN Clause | 官方文档 | 仅用于核对连接语义与错误码,不是课程材料 |
本集无逐字稿(匿名 player/v2 返回 subtitles=[]、need_login_subtitle=true),依据平台标题、讲义 p69–72「5.1 多表关系」与公开静帧核对;多对多部分以 t≈292s 静帧(中间表)为准。一对一、一对多的表述为同主题通用整理。示例表与数据为本笔记自建,不是课程原表。
讲义对照:讲义 5.1 多表关系(一对多 / 多对多 / 一对一) · p69–72(公开镜像;按主题对应,切点 notexact)
- 画面静帧 9 帧,采样点 0:12–11:59 / 全片 12:12(只用于确认画面主题,不作内容边界)
- 原声字幕未取得:匿名接口字幕轨为空且需登录,未使用任何账号
等级含义:平台视频页 / 官方文档 / 课件 = 原始材料;二手整理 = 参考;推断 = 未经核实。站内补充的解释与练习会在此说明。