目录

第2章 关系模型

🪶 第15课:关系代数——专门的关系运算(选择、投影)

🎓 第一部分:专业学术讲解

1. 专门的关系运算有哪些?

2. 选择(Selection)

3. 投影(Projection)

4. 选择和投影的组合

5. 选择的条件写法

🏠 第二部分:通俗生活化讲解

🧸 故事引入:一张完整的成绩单

🧸 选择:只看某些“行”

🧸 投影:只看某些“列”

🧸 组合使用:先选行,再选列

🧸 第四部分:本课小结

🌟 课后一个小问题

🪶 第16课:关系代数——专门的关系运算(连接、除)

🎓 第一部分:专业学术讲解

🧸 各种连接详解

一、为什么需要连接?

二、连接的本质

三、准备好例子数据

四、θ连接(Theta Join)

定义

写法

例子

五、等值连接(Equi Join)

定义

写法

例子

六、自然连接(Natural Join)⭐

定义

规则

写法

例子

对比等值连接

七、外连接(Outer Join)

问题引出

7.1 左外连接(Left Outer Join)

7.2 右外连接(Right Outer Join)

7.3 全外连接(Full Outer Join)

外连接对比表

八、各种连接的结果对比

九、什么时候用哪种连接?

🧸 多表连接详解

一、直接回答

二、多表连接的原理

核心思想

执行过程

三、具体例子

需求:查询每个学生的姓名、课程名、成绩、任课教师

四、多表连接的写法

关系代数写法

SQL写法(实际使用的语言)

五、多表连接的顺序

问题:连接的顺序重要吗?

例子

六、多表连接的几种模式

1. 链式连接(最常见)

2. 星型连接(数据仓库常见)

3. 多路连接

本课小结

🌟 课后一个小问题

🧸 除运算详解

例子1:基础版——选修了所有课程的学生

例子2:带多个公共属性

一、问题的本质

二、具体例子:为什么需要自己指定?

例子:查询“选修了所有数学课的学生”

如果用数学除运算(自动找所有公共属性)

但如果S中有“学期”呢?

三、解决方案:投影 + 除运算

四、通用模式:带投影的除运算

五、对比:数学除 vs 现实除

七、总结

一、除运算是什么?

定义

通俗理解

符号

二、除运算的本质

数学定义

三个关键点

一句话

三、除运算的步骤

标准步骤(4步法)

四、具体例子(由简到难)

例子1:基础版——选修了所有课程的学生

例子2:带多个公共属性

例子3:S只有一行

例子4:S为空

五、除运算 vs 其他运算

关键区别

六、除运算的常见应用场景

七、除运算的SQL实现

方法1:GROUP BY + HAVING

方法2:NOT EXISTS双重否定

九、常见易错点

十、本课小结

🌟 课后小问题


第2章 关系模型

🪶 第15课:关系代数——专门的关系运算(选择、投影)

对应教材:2.4.2 专门的关系运算


🎓 第一部分:专业学术讲解

这是关系代数中最常用、最重要的运算。


1. 专门的关系运算有哪些?
运算 符号 作用 操作对象
选择 σ 选取满足条件的 单个表
投影 π 选取指定的 单个表
连接 把两个表按条件合并 两个表
÷ 查找“同时满足一组条件”的数据 两个表

今天这节课,我们先学选择投影


2. 选择(Selection)

选择:从关系(表)中选取满足指定条件的元组(行)。

写法

σ 条件 (关系名)

例子

σ 年龄 > 20 (学生)

举例

学号 姓名 年龄 专业
001 张三 20 计算机
002 李四 21 软件工程
003 王五 19 计算机

σ 年龄 > 20 (学生) 的结果:

学号 姓名 年龄 专业
002 李四 21 软件工程

🧸 选择 = 选行,就像在Excel里用筛选功能,只显示符合条件的行。


3. 投影(Projection)

投影:从关系(表)中选取指定的属性(列)。

写法

π 属性1, 属性2, ... (关系名)

例子

π 姓名, 专业 (学生)

举例

学号 姓名 年龄 专业
001 张三 20 计算机
002 李四 21 软件工程
003 王五 19 计算机

π 姓名, 专业 (学生) 的结果:

姓名 专业
张三 计算机
李四 软件工程
王五 计算机

🧸 投影 = 选列,就像在Excel里隐藏某些列,只显示你需要的列。


4. 选择和投影的组合

任何东西的设计都是为实际应用所服务,数据库也不例外,在实际情况中,选择和投影几乎是捆绑使用的,例如,三班的语文老师只关注三班的语文成绩,并不关注其他班的成绩,也不关注三班的非语文成绩

选择和投影可以组合使用。先选择,再投影是最常见的操作顺序。

例子:找出年龄>20的学生的姓名和专业

第一步:选择

σ 年龄 > 20 (学生)

得到:

学号 姓名 年龄 专业
002 李四 21 软件工程

第二步:投影

π 姓名, 专业 ( σ 年龄 > 20 (学生) )

得到:

姓名 专业
李四 软件工程

🧸 先选行,再选列——这是最常用的查询模式。


5. 选择的条件写法
条件类型 写法 例子
比较 >, <, =, ≥, ≤, ≠ 年龄 > 20
逻辑与 ∧(或 AND) 年龄 > 20 ∧ 专业 = '计算机'
逻辑或 ∨(或 OR) 专业 = '计算机' ∨ 专业 = '软件工程'
逻辑非 ¬(或 NOT) ¬(年龄 > 20)

🏠 第二部分:通俗生活化讲解

好的,专业概念先到这里。现在,我们用你完全能懂的方式来理解“选择”和“投影”。


🧸 故事引入:一张完整的成绩单

想象你手里有一张全班同学的成绩单:

学号 姓名 班级 语文 数学 英语
001 张小萌 3班 85 92 88
002 李小乐 3班 78 95 82
003 王小宝 4班 90 88 91
004 赵小美 4班 82 79 85

这张表里有太多信息了。有时候你只想看一部分。


🧸 选择:只看某些“行”

场景一:你想看3班同学的成绩。

你“选择”班级='3班'的行:

学号 姓名 班级 语文 数学 英语
001 张小萌 3班 85 92 88
002 李小乐 3班 78 95 82

🧸 选择 = 按条件筛选行


场景二:你想看数学≥90分的同学。

你“选择”数学≥90的行:

学号 姓名 班级 语文 数学 英语
001 张小萌 3班 85 92 88
002 李小乐 3班 78 95 82

选择就是精确地按条件筛选。


🧸 投影:只看某些“列”

场景:你想发一个通知,只需要知道学生的“姓名”和“班级”。

你“投影”出姓名和班级这两列:

姓名 班级
张小萌 3班
李小乐 3班
王小宝 4班
赵小美 4班

🧸 投影 = 按列筛选,只保留你需要的列。


🧸 组合使用:先选行,再选列

场景:你想知道“3班同学的姓名和语文成绩”。

第一步:选择(选行)——选出3班的行

学号 姓名 班级 语文 数学 英语
001 张小萌 3班 85 92 88
002 李小乐 3班 78 95 82

第二步:投影(选列)——只保留姓名和语文

姓名 语文
张小萌 85
李小乐 78

🧸 组合使用 = 先筛选行,再筛选列


🧸 第四部分:本课小结

今天我们学习了选择投影

运算 符号 作用 生活类比
选择 σ 选取满足条件的 Excel筛选
投影 π 选取指定的 Excel隐藏列

核心要点

  • 选择 = 选行(横向筛选)

  • 投影 = 选列(纵向筛选)

  • 两者经常组合使用:先选行,再选列

一句话记住这节课

选择是选行,投影是选列;先选行再选列,就能得到你想要的数据子集。


🌟 课后一个小问题

还是那张成绩单:

学号 姓名 班级 语文 数学
001 张三 1班 85 90
002 李四 2班 78 88
003 王五 1班 92 85

请用关系代数的表达式写出以下查询:

  1. 找出所有1班的学生

  2. 只显示所有学生的姓名和数学成绩

  3. 找出1班学生的姓名和语文成绩

🪶 第16课:关系代数——专门的关系运算(连接、除)

对应教材:2.4.2 专门的关系运算


🎓 第一部分:专业学术讲解

上节课我们学习了选择(选行)和投影(选列),它们是对单个表的操作。

今天这节课,我们来学习如何把多个表连接起来——这是关系代数中最强大、也最常用的运算。

🧸 各种连接详解

连接分为θ连接,等值连接,自然连接,外连接,其中等值连接是特殊的θ连接,是θ连接中条件为等值时的连接,需要注意的是:若两表中有多个属性相同,等值连接并不需要保证全部的属性都等值,只需要保证你指定的属性相同即可,不是你指定的则无所谓,但是自然连接是全部都需要相等。

自然连接是等值连接的升级变异版,因为自然连接会自动选择两表中相同的属性,进行等值连接,而且在连接之后还会删除重复的行,与实际应用相符,故而最常用,且若两表中有多个属性相同,自然连接是全部都需要相等。

因为连接都涉及到了匹配问题,故而定然存在没有匹配对象的情况,也就是在关系B中没有与关系A中某元组相匹配的元组,此时就涉及到了外连接,正常连接对于这些没有匹配的元组会直接删去,但是某些情况下不能删或者删了会有不好的影响,外连接的作用就是保留这些没有匹配的元组,将其对应属性设置为NULL(空)

好的!这一课我们把所有连接类型一个一个讲透,不跳步。


一、为什么需要连接?

问题:在关系数据库中,数据是分散存储在多张表中的。

  • 学生表存学生信息

  • 成绩表存成绩信息

  • 课程表存课程信息

需求:我们经常需要把多张表的信息合在一起看。比如:

“查询每个学生的姓名和成绩”

这需要把学生表成绩表连接起来。

解决方案:连接运算。


二、连接的本质

连接 = 笛卡尔积 + 选择

步骤 做什么 结果大小
第一步 做笛卡尔积(R × S) R × S
第二步 按条件选择(σ) R × S

🧸 理解:笛卡尔积把两表所有行两两配对,然后只保留满足条件的配对。


三、准备好例子数据

为了讲清楚各种连接,我们用同一个例子贯穿始终。

表R:学生表

学号 姓名
001 张三
002 李四
003 王五

表S:成绩表

学号 课程 分数
001 数学 85
001 语文 90
003 数学 78

注意

  • 张三(001)有两门成绩

  • 李四(002)没有成绩

  • 王五(003)有一门成绩


四、θ连接(Theta Join)

定义

在笛卡尔积上做条件选择,条件可以是任何比较运算(>、<、=、≠、≥、≤)。

写法

R ⨝ S
   θ

其中θ是条件表达式。

例子

例子1:等值条件(就是比较运算符是‘=’)

R ⨝ S
   R.学号 = S.学号

先做笛卡尔积(3行 × 3行 = 9行):

R.学号 姓名 S.学号 课程 分数
001 张三 001 数学 85
001 张三 001 语文 90
001 张三 003 数学 78
002 李四 001 数学 85
002 李四 001 语文 90
002 李四 003 数学 78
003 王五 001 数学 85
003 王五 001 语文 90
003 王五 003 数学 78

再选择 R.学号 = S.学号:

R.学号 姓名 S.学号 课程 分数
001 张三 001 数学 85
001 张三 001 语文 90
003 王五 003 数学 78

例子2:非等值条件

R ⨝ S
   R.学号 < S.学号

从9行笛卡尔积中,选出 R.学号 < S.学号 的行:

R.学号 姓名 S.学号 课程 分数
001 张三 003 数学 78
002 李四 003 数学 78

🧸 条件不一定是等号,可以是大于、小于、不等于等。


五、等值连接(Equi Join)

定义

θ条件为“=”的连接。

写法

R ⨝ S
   R.学号 = S.学号

例子

结果和上面等值条件的θ连接一样:

R.学号 姓名 S.学号 课程 分数
001 张三 001 数学 85
001 张三 001 语文 90
003 王五 003 数学 78

🧸 等值连接是θ连接的特例,只是条件固定为“=”。


六、自然连接(Natural Join)⭐

定义

在等值连接的基础上,自动去掉重复的列

规则

  1. 自动寻找两个表中同名且同类型的列

  2. 以这些列相等为连接条件

  3. 结果中只保留一份这些同名列

写法

R ⨝ S

(不需要写条件,系统自动找)

例子

R和S都有“学号”列,且类型相同。自然连接自动按 R.学号 = S.学号 连接,并只保留一个学号列:

学号 姓名 课程 分数
001 张三 数学 85
001 张三 语文 90
003 王五 数学 78

对比等值连接

等值连接 自然连接
学号列 出现两次(R.学号, S.学号) 出现一次
连接条件 必须显式写出 自动寻找
结果 可能有重复列 无重复列

🧸 自然连接是最常用的连接,因为它简洁且不产生冗余列。


七、外连接(Outer Join)

问题引出

在自然连接中,李四(002)没有成绩,所以被丢掉了

学号 姓名 课程 分数
001 张三 数学 85
001 张三 语文 90
003 王五 数学 78
~~002~~ ~~李四~~ ~~被丢掉了~~

外连接:保留不匹配的元组,缺失的值用NULL填充。


7.1 左外连接(Left Outer Join)

定义:保留左表的所有元组。

符号:⟕

写法:R ⟕ S

例子:学生表在左,成绩表在右

学号 姓名 课程 分数
001 张三 数学 85
001 张三 语文 90
002 李四 NULL NULL ← 李四没有成绩,填空NULL
003 王五 数学 78

🧸 左外连接 = 左表全部保留 + 右表能匹配就匹配,不能匹配就填NULL


7.2 右外连接(Right Outer Join)

定义:保留右表的所有元组。

符号:⟖

写法:R ⟖ S

例子

学号 姓名 课程 分数
001 张三 数学 85
001 张三 语文 90
003 王五 数学 78

咦,看起来和自然连接一样?因为右表(成绩表)的所有学号(001、001、003)在左表中都有匹配。如果右表有学号在左表不存在,就会填空NULL。

🧸 右外连接 = 右表全部保留 + 左表能匹配就匹配,不能匹配就填NULL


7.3 全外连接(Full Outer Join)

定义:保留两个表的所有元组。

符号:⟗

写法:R ⟗ S

例子

学号 姓名 课程 分数
001 张三 数学 85
001 张三 语文 90
002 李四 NULL NULL
003 王五 数学 78

🧸 全外连接 = 左表全部保留 + 右表全部保留,不能匹配的填NULL


外连接对比表

类型 保留左表 保留右表 不匹配的处理
左外连接 ✅ 全部 ❌ 只保留匹配的 右表填NULL
右外连接 ❌ 只保留匹配的 ✅ 全部 左表填NULL
全外连接 ✅ 全部 ✅ 全部 两边都填NULL

八、各种连接的结果对比

用同一个例子,把所有连接的结果放在一起对比:

R(学生表):001张三、002李四、003王五
S(成绩表):(001,数学,85)、(001,语文,90)、(003,数学,78)

连接类型 学号 姓名 课程 分数 说明
θ连接(=) 001 张三 数学 85 有R.学号和S.学号两列
001 张三 语文 90
003 王五 数学 78
自然连接 001 张三 数学 85 去掉重复学号列
001 张三 语文 90
003 王五 数学 78
左外连接 001 张三 数学 85 保留李四
001 张三 语文 90
002 李四 NULL NULL
003 王五 数学 78
右外连接 001 张三 数学 85 右表全保留
001 张三 语文 90
003 王五 数学 78
全外连接 001 张三 数学 85 两表全保留
001 张三 语文 90
002 李四 NULL NULL
003 王五 数学 78

🧸 注意:这个例子中右外连接和自然连接结果相同,是因为右表的所有学号都在左表中有匹配。


九、什么时候用哪种连接?

场景 推荐连接 原因
只需要匹配的数据 自然连接 简洁,无冗余
需要保留左表所有数据 左外连接 例如:查所有学生,没有成绩也要显示
需要保留右表所有数据 右外连接 例如:查所有课程,没有被选的也要显示
需要保留两表所有数据 全外连接 例如:对比两个表的差异
需要非等值条件 θ连接 例如:分数比自己高的同学
只需要相等条件,不关心去重 等值连接 需要保留两边的学号列时

🧸 多表连接详解

学到这我想到了一个问题,实际情况下,表的连接肯定不会只涉及到两个表,但是ds却说连接和除都是对两个表进行的操作,故而我单独问了一下ds,答案是连接和除确实是对两个表进行的操作,对于多个表的连接,是通过多次连接得到的,比如有A,B,C三个表,我们先连接AB,得到一个临时表,再把这个临时表和C连接,此时就完成了多表连接操作


一、直接回答

连接不仅限于两个表,多个表也可以连接。

事实上,在实际的数据库查询中,连接3个、4个甚至更多个表是非常常见的操作。


二、多表连接的原理

核心思想

连接是二元运算,一次只连接两个表。连接多个表时,是多次连接的结果

执行过程

((R ⨝ S) ⨝ T) ⨝ U ...

步骤

  1. 先连接R和S,得到中间结果RS

  2. 再把RS和T连接,得到RST

  3. 再把RST和U连接……

  4. 直到所有表都连接完成

🧸 理解:就像加法,一次只能加两个数,但可以连续加很多次。


三、具体例子

假设有四张表:

学生表(S)

学号 姓名
001 张三
002 李四

选课表(SC)

学号 课程号 成绩
001 C01 85
001 C02 90
002 C01 78

课程表(C)

课程号 课程名
C01 数据库
C02 操作系统

教师表(T)

课程号 教师名
C01 王老师
C02 李老师

需求:查询每个学生的姓名、课程名、成绩、任课教师

这需要连接4张表

执行过程

第一步:连接学生表和选课表

S ⨝ SC

结果(临时表1):

学号 姓名 课程号 成绩
001 张三 C01 85
001 张三 C02 90
002 李四 C01 78

第二步:连接临时表1和课程表

(S ⨝ SC) ⨝ C

结果(临时表2):

学号 姓名 课程号 成绩 课程名
001 张三 C01 85 数据库
001 张三 C02 90 操作系统
002 李四 C01 78 数据库

第三步:连接临时表2和教师表

((S ⨝ SC) ⨝ C) ⨝ T

最终结果:

学号 姓名 课程号 成绩 课程名 教师名
001 张三 C01 85 数据库 王老师
001 张三 C02 90 操作系统 李老师
002 李四 C01 78 数据库 王老师

四、多表连接的写法

关系代数写法

π 姓名, 课程名, 成绩, 教师名 (
    ((S ⨝ SC) ⨝ C) ⨝ T
)

SQL写法(实际使用的语言)

SELECT S.姓名, C.课程名, SC.成绩, T.教师名
FROM 学生表 S
JOIN 选课表 SC ON S.学号 = SC.学号
JOIN 课程表 C ON SC.课程号 = C.课程号
JOIN 教师表 T ON C.课程号 = T.课程号

🧸 注意:SQL中的JOIN默认是自然连接/等值连接的效果。


五、多表连接的顺序

问题:连接的顺序重要吗?

答案:逻辑上不重要(结果相同),但性能上很重要

例子

连接三张表:A ⨝ B ⨝ C

顺序1:(A ⨝ B) ⨝ C
顺序2:(A ⨝ C) ⨝ B
顺序3:(B ⨝ C) ⨝ A

逻辑上:结果相同(只要连接条件正确)

性能上:中间结果的大小不同

顺序 中间结果大小 可能的问题
先连接小表
先连接大表

🧸 优化原则:先连接能产生较小结果集的表对。


六、多表连接的几种模式

1. 链式连接(最常见)

表与表之间像链条一样连接:

A ── B ── C ── D

例子:学生 → 选课 → 课程 → 教师

每个表与相邻的表有连接条件。


2. 星型连接(数据仓库常见)

一个中心表连接多个外围表:

      B
       \
        \
A ────── C
        /
       /
      D

例子:销售记录表(事实表)连接 产品表、时间表、门店表、客户表


3. 多路连接

多个表同时连接,条件比较复杂:

A ⨝ B ⨝ C
条件:A.x = B.x AND B.y = C.y AND A.z = C.z

形成循环连接。


本课小结

知识点 核心内容
多表连接 连接是二元运算,多表连接是多次连接
连接顺序 逻辑上结果相同,性能上不同
链式连接 最常见,表与表像链条一样连接
星型连接 数据仓库中常见,一个中心表连接多个外围表
优化原则 先连接能产生较小结果集的表

一句话记住这节课

多表连接就是多次二元连接,先连两个表,再把结果连下一个表,以此类推;连接的顺序影响性能,但不影响最终结果。


🌟 课后一个小问题

有四张表:

  • 订单表(订单号,客户号,订单日期)

  • 客户表(客户号,客户名,城市)

  • 订单明细表(订单号,商品号,数量)

  • 商品表(商品号,商品名,单价)

如果要查询“每个订单的客户名、订单日期、商品名、数量、总价(数量×单价)”,需要连接哪几张表?连接顺序应该是怎样的?

🧸 除运算详解

除运算比较难理解,一开始ds是和连接一起讲的,但是连接和除的知识点太多了,ds就会讲的很简略,后来我让ds分开讲解连接和除,两者大概的意思明白的差不多了,我的理解:除也是匹配,但是和正常匹配不太一样,除着重于“全部”这个词语,对于两个表,假设为表A和表B,表A÷表B,结果返回A中与B全部匹配的值,这有几个需要注意的点:

①:A具体是和B中的什么进行匹配?

要想匹配,肯定是对于相同的属性进行操作,相同属性具体来说就是AB的公共属性,A匹配的对象就是B中和A公共的属性下的全部元组(B中和A公共的属性下的全部行),B中公共属性下的全部行都需要匹配到才可

具体例子:

例子1:基础版——选修了所有课程的学生

A(选课表)

学号 课程
001 数学
001 语文
001 英语
002 数学
002 英语
003 数学

B(课程表)

课程
数学
语文
英语

AB的公共属性是课程,B课程属性下全部行为数学,语文,英语

在A中找与这些行全部匹配的东西,最终找到是:

学号
001

这便是A÷B的结果,相信你也注意到了,这个结果只保留了学号这一属性,并没有保留课程,因为:A ÷ B 的结果只保留 A 中【不属于 B】的那些属性(即非公共属性)。

例子2:带多个公共属性

R(选课成绩表)

学号 课程 学期
001 数学 2024秋
001 语文 2024秋
001 英语 2024秋
002 数学 2024秋
002 英语 2024秋
003 数学 2024秋
001 数学 2025春
001 语文 2025春

S(指定条件)

课程 学期
数学 2024秋
语文 2024秋

结果:

学号
001

②:怎么进行匹配?(具体操作步骤是什么?)

步骤1:确定R和S的公共属性(连接属性)

步骤2:计算S在公共属性上的投影(S中所有可能的值)

步骤3:对R中每个候选元组,检查它是否与S的所有值都有配对

步骤4:只保留满足条件的元组

③:最后输出的是什么?

A ÷ B 的结果只保留 A 中【不属于 B】的那些属性(即非公共属性)

④这些公共属性是自动全部匹配吗?还是说可以根据实际情况部分匹配。

我学完除运算后最疑惑的问题就是这个,我问了ds之后得到了答案:公共属性是全部都自动进行匹配(类似于自然连接),此时我又有了一个新的疑问,在实际情况中,对于有多个公共属性的关系来说,我们的查询可能只看某个公共属性,而不关心全部的公共属性,那这个除就有点死板了,我问了ds,ds回答我:

在实际应用中,确实有指定部分属性做“全部”查询的需求。

除运算的“自动找所有公共属性”是数学定义,但现实中我们经常需要自己指定要匹配哪些属性。


一、问题的本质

除运算的数学定义要求:所有公共属性都要匹配。

但现实需求往往是:我只关心某几个属性是否“全部”满足,其他属性我不关心。

数学除运算 现实需求
自动找所有公共属性 用户指定要匹配的属性
要求所有公共属性都匹配 只要求指定的属性匹配
不能灵活指定 需要灵活指定

🧸 结论:数学除运算是基础,实际使用时需要“增强版”——带投影的除运算


二、具体例子:为什么需要自己指定?

例子:查询“选修了所有数学课的学生”

R(选课表)

学号 课程 学期 成绩
001 微积分 2024春 85
001 线性代数 2024秋 90
001 概率论 2025春 88
002 微积分 2024秋 78
002 线性代数 2024秋 82
003 微积分 2024秋 92

S(数学课程表)

课程
微积分
线性代数
概率论

如果用数学除运算(自动找所有公共属性)

公共属性 = {课程}(R和S都有“课程”)

R ÷ S 的结果:

学号
001

没问题,结果正确。


但如果S中有“学期”呢?

S(数学课程表,带学期要求)

课程 学期
微积分 2024秋
线性代数 2024秋

数学除运算:公共属性 = {课程, 学期}

R ÷ S 的结果:

为空


三、解决方案:投影 + 除运算

步骤:先把R投影到我们关心的属性上,再做除运算。

需求:查询“选修了微积分和线性代数这两门课的学生”(忽略学期)

第一步:把R投影到(学号,课程)上

π 学号, 课程 (R)

学号 课程
001 微积分
001 线性代数
001 概率论
002 微积分
002 线性代数
003 微积分

第二步:用投影后的R做除运算

π 学号, 课程 (R) ÷ S

学号
001
002

🧸 结果:001和002都选修了微积分和线性代数(不管在哪个学期)。


四、通用模式:带投影的除运算

需求:查询“在属性集X上,满足S中所有条件的元组”

公式

π ( R ) ÷ S
  X

其中X是你关心的属性集合。

步骤 操作 作用
1 投影 π_X (R) 只保留你关心的属性
2 除运算 ÷ S 在投影结果上做“全部”查询

🧸 这就是现实中的做法:先投影,再除。


五、对比:数学除 vs 现实除

对比项 数学除运算 现实中的做法
公共属性 自动找所有 用户指定(通过先投影)
匹配要求 所有公共属性 用户指定的那些
灵活性

现实中的SQL实现(没有直接的除,用其他方式):

-- 查询选修了微积分和线性代数的学生
SELECT 学号
FROM 选课表
WHERE 课程 IN ('微积分', '线性代数')
GROUP BY 学号
HAVING COUNT(DISTINCT 课程) = 2

🧸 这里就是自己指定了要匹配的属性:课程(忽略学期)。


七、总结

问题 答案
数学除运算是自动找公共属性吗? 是的。自动找R和S的所有同名属性
现实中能自己指定吗? 。通过“先投影,再除”实现
为什么需要自己指定? 因为实际需求往往只关心部分属性,不关心其他属性
怎么做? π 关心的属性 (R) ÷ π 关心的属性 (S)

🧸 核心:数学除运算是理论基础,实际使用时可以灵活组合投影和除运算来实现“指定部分属性”的需求。

通过这个我们可以发现,选择,投影,连接,除,这四个专门的关系运算以及之前学的传统运算都很重要,在实际情况中还会涉及他们的搭配使用。


一、除运算是什么?

定义

除运算:R ÷ S 的结果是满足以下条件的元组:在R中,它与S中的每一个元组都有配对。

通俗理解

除运算 = “全部”查询

  • 查询“选修了所有课程的学生”

  • 查询“购买了所有商品的顾客”

  • 查询“参加了全部社团活动的同学”

符号

R ÷ S

二、除运算的本质

数学定义

R ÷ S = { t | t ∈ π (R) ∧ ∀ s ∈ S ( (t,s) ∈ R ) }
              属性集

我在用ds学数据库的同时也在看数上讲的,书上一堆奇奇怪怪的符号,对于初学者根本看不懂也根本看不下去。。。

三个关键点

关键点 说明
t R中除去S的属性后的元组
∀ s ∈ S 对于S中的每一个元组
(t,s) ∈ R (t,s)这个组合在R中存在

一句话

找出R中那些与S中所有元组都配对过的元组。


三、除运算的步骤

标准步骤(4步法)

步骤1:确定R和S的公共属性(连接属性)

步骤2:计算S在公共属性上的投影(S中所有可能的值)

步骤3:对R中每个候选元组,检查它是否与S的所有值都有配对

步骤4:只保留满足条件的元组


四、具体例子(由简到难)

例子1:基础版——选修了所有课程的学生

R(选课表)

学号 课程
001 数学
001 语文
001 英语
002 数学
002 英语
003 数学

S(课程表)

课程
数学
语文
英语

执行步骤

步骤1:公共属性是“课程”

步骤2:S在“课程”上的值 = {数学, 语文, 英语}

步骤3:检查每个学生:

学号 选修的课程 是否包含{数学,语文,英语}?
001 {数学,语文,英语} ✅ 是
002 {数学,英语} ❌ 否(缺语文)
003 {数学} ❌ 否(缺语文、英语)

步骤4:结果

学号
001

R ÷ S = {001}

🧸 解释:只有001选修了S中的所有课程。


例子2:带多个公共属性

R(选课成绩表)

学号 课程 学期
001 数学 2024秋
001 语文 2024秋
001 英语 2024秋
002 数学 2024秋
002 英语 2024秋
003 数学 2024秋
001 数学 2025春
001 语文 2025春

S(指定条件)

课程 学期
数学 2024秋
语文 2024秋

执行步骤

步骤1:公共属性是(课程,学期)——两个属性!

步骤2:S中的组合 = {(数学,2024秋), (语文,2024秋)}

步骤3:检查每个学生:

学号 在R中的(课程,学期)组合 是否包含S的所有组合?
001 {(数学,2024秋),(语文,2024秋),(英语,2024秋),(数学,2025春),(语文,2025春)} ✅ 是
002 {(数学,2024秋),(英语,2024秋)} ❌ 否(缺语文,2024秋)
003 {(数学,2024秋)} ❌ 否(缺语文,2024秋)

步骤4:结果

学号
001

🧸 解释:公共属性可以是多个列的组合。S中有几行,每个学生就必须有几行配对。


例子3:S只有一行

R(选课表)

学号 课程
001 数学
001 语文
002 数学
003 数学

S(指定课程)

课程
数学

R ÷ S

学号
001
002
003

🧸 解释:当S只有一行时,除运算等价于投影 + 去重——找出所有选修了数学的学生。


例子4:S为空

R(选课表)

学号 课程
001 数学
002 数学

S(空表,没有行)


R ÷ S

学号
001
002

🧸 解释:S为空时,条件“与S中每一个元组都配对”是空真(没有任何限制),所以返回R中所有候选元组。


五、除运算 vs 其他运算

运算 作用 例子
选择(σ) 按条件筛选行 找出成绩≥90的学生
投影(π) 按列筛选 只看学号和姓名
连接(⨝) 把两个表合并 把学生表和成绩表合并
除(÷) 找“全部” 找出选修了所有课程的学生

关键区别

  • 连接:找“有”配对

  • 除:找“有所有”配对

🧸 连接问的是:“这个学生选了数学吗?”(存在性)

问的是:“这个学生选了所有课程吗?”(全体性)


六、除运算的常见应用场景

场景 R是什么 S是什么 结果
选修了所有课程的学生 选课表(学号,课程) 课程表(课程) 学号
购买了全部商品的顾客 购买记录(顾客ID,商品ID) 商品表(商品ID) 顾客ID
参加了所有活动的员工 参与记录(员工ID,活动ID) 活动表(活动ID) 员工ID
在所有部门都工作过的员工 工作记录(员工ID,部门ID) 部门表(部门ID) 员工ID

七、除运算的SQL实现

标准的SQL没有直接的“除”运算,但可以用其他方式实现:

方法1:GROUP BY + HAVING

sql

SELECT 学号
FROM 选课表
WHERE 课程 IN ('数学', '语文', '英语')
GROUP BY 学号
HAVING COUNT(DISTINCT 课程) = 3

方法2:NOT EXISTS双重否定

sql

SELECT DISTINCT 学号
FROM 选课表 R1
WHERE NOT EXISTS (
    SELECT 课程 FROM 课程表 S
    WHERE NOT EXISTS (
        SELECT * FROM 选课表 R2
        WHERE R2.学号 = R1.学号
        AND R2.课程 = S.课程
    )
)

🧸 理解:没有一门课程是这个学生没选的 = 选了所有课程。


九、常见易错点

易错点 正确理解
搞混除和连接 连接找“有配对”,除找“有所有配对”
忽略公共属性 公共属性可能是多个列的组合
忘记去重 结果中不会有重复元组
S为空时结果为空 不对!S为空时,结果是R中所有候选元组

十、本课小结

知识点 核心内容
除运算的定义 找出与S中每一个元组都有配对的R中的元组
核心应用 “全部”查询:选了所有课、买了所有商品……
执行步骤 4步法:找公共属性 → 找S的值集 → 检查每个候选 → 输出
与连接的区别 连接是“存在”,除是“全部”

一句话记住这节课

除运算是关系代数中的“全部”查询——找出那些与S中每一个元组都有配对的元组,就像找“选修了所有课程的学生”。


🌟 课后小问题

有两个表:

R(仓库库存表)

仓库号 商品号
W01 P01
W01 P02
W01 P03
W02 P01
W02 P02
W03 P01

S(商品清单)

商品号
P01
P02
P03

问:R ÷ S 的结果是什么?它表示什么含义?

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐