关系代数详解
关系代数是关系数据库的理论基础,提供了一套完整的数据查询操作集合。本文详细介绍关系代数的八种基本运算及其数学表示。
目录
- [第一章 关系代数概述](#第一章 关系代数概述)
- [第二章 传统集合运算](#第二章 传统集合运算)
- [第三章 专门关系运算](#第三章 专门关系运算)
- [第四章 扩展关系运算](#第四章 扩展关系运算)
- [第五章 运算符优先级与表达式](#第五章 运算符优先级与表达式)
- [第六章 关系代数与SQL对照](#第六章 关系代数与SQL对照)
- [第七章 综合练习与案例](#第七章 综合练习与案例)
- [第八章 面试与考试重点](#第八章 面试与考试重点)
第一章 关系代数概述
关系代数是关系数据库的理论基础,理解它对于深入掌握SQL和数据库查询优化至关重要。
1.1 什么是关系代数
定义
关系代数(Relational Algebra) 是一种抽象的查询语言,它使用对关系的运算来表达查询。简单来说:
┌─────────────────────────────────────────────────────────────────┐
│ 关系代数的本质 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 输入:一个或多个关系(表) │
│ ↓ │
│ 运算:对关系进行各种操作 │
│ ↓ │
│ 输出:一个新的关系(表) │
│ │
│ 核心思想:关系进 → 关系出(封闭性) │
│ │
└─────────────────────────────────────────────────────────────────┘
起源
- 1970年:E.F. Codd 在其经典论文中提出关系模型
- 关系代数是Codd为关系模型定义的两种形式化查询语言之一
- 另一种是关系演算(Relational Calculus)
与关系演算的区别
| 比较项 | 关系代数 | 关系演算 |
|---|---|---|
| 性质 | 过程化语言 | 非过程化语言 |
| 描述方式 | "如何做" | "要什么" |
| 操作方式 | 指定运算步骤 | 只描述结果条件 |
| 理论基础 | 集合论 | 谓词逻辑 |
| 类比 | 像菜谱(步骤) | 像点菜(结果) |
通俗理解:
- 关系代数:告诉数据库"先做A,再做B,最后做C"
- 关系演算:告诉数据库"我要满足X条件的数据"
在数据库中的地位
┌─────────────────────────────────────────────────────────────────┐
│ 关系代数的重要性 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. SQL的理论基础 │
│ • SQL是基于关系代数和关系演算设计的 │
│ • 理解关系代数有助于写出更好的SQL │
│ │
│ 2. 查询优化的基础 │
│ • 数据库优化器使用关系代数规则进行查询优化 │
│ • 等价变换规则用于生成更高效的执行计划 │
│ │
│ 3. 数据库理论的核心 │
│ • 证明查询等价性 │
│ • 分析查询复杂度 │
│ │
└─────────────────────────────────────────────────────────────────┘
1.2 关系代数的分类
关系代数的运算可以分为三大类:
┌─────────────────────────────────────────────────────────────────┐
│ 运算分类 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 一、传统集合运算(基于集合论) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 并(Union) ∪ 合并两个关系的元组 │ │
│ │ • 交(Intersection) ∩ 取两个关系的公共元组 │ │
│ │ • 差(Difference) - 从R中去除S中也有的元组 │ │
│ │ • 笛卡尔积(Product) × 所有元组的组合 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 二、专门关系运算(为关系数据库设计) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 选择(Selection) σ 按条件选择行(水平切分) │ │
│ │ • 投影(Projection) π 选择列(垂直切分) │ │
│ │ • 连接(Join) ⋈ 关联两个关系 │ │
│ │ • 除法(Division) ÷ "全部"类型查询 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 三、扩展运算(实际应用扩展) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 外连接(Outer Join) 保留不匹配的元组 │ │
│ │ • 半连接(Semi Join) 只返回匹配的一侧 │ │
│ │ • 聚集(Aggregation) COUNT, SUM, AVG等 │ │
│ │ • 分组(Grouping) GROUP BY操作 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
五种基本运算:
在八种运算中,以下五种是基本运算,其他运算都可以由它们表示:
| 基本运算 | 符号 | 说明 |
|---|---|---|
| 并 | ∪ | 合并元组 |
| 差 | - | 去除元组 |
| 笛卡尔积 | × | 组合元组 |
| 选择 | σ | 选择行 |
| 投影 | π | 选择列 |
交、连接、除法都可用这五种基本运算表示
1.3 关系代数的基本符号
关系与元组符号
基本符号约定:
┌──────────────────┬────────────────────────────────────────────┐
│ 符号 │ 含义 │
├──────────────────┼────────────────────────────────────────────┤
│ R, S, T │ 关系(表)的名称 │
├──────────────────┼────────────────────────────────────────────┤
│ t, u, v │ 元组(行) │
├──────────────────┼────────────────────────────────────────────┤
│ A, B, C │ 属性(列)名称 │
├──────────────────┼────────────────────────────────────────────┤
│ a₁, a₂, ... │ 属性的替代表示 │
├──────────────────┼────────────────────────────────────────────┤
│ t[A] │ 元组t在属性A上的值 │
├──────────────────┼────────────────────────────────────────────┤
│ t ∈ R │ 元组t属于关系R │
├──────────────────┼────────────────────────────────────────────┤
│ |R| │ 关系R的元组数(基数) │
└──────────────────┴────────────────────────────────────────────┘
运算符号速查表
| 运算 | 符号 | 读法 | 类型 | 输入 | 输出 |
|---|---|---|---|---|---|
| 并 | ∪ | Union | 二元 | 两个关系 | 一个关系 |
| 交 | ∩ | Intersection | 二元 | 两个关系 | 一个关系 |
| 差 | - | Difference | 二元 | 两个关系 | 一个关系 |
| 笛卡尔积 | × | Cross Product | 二元 | 两个关系 | 一个关系 |
| 选择 | σ | Sigma | 一元 | 一个关系 | 一个关系 |
| 投影 | π | Pi | 一元 | 一个关系 | 一个关系 |
| 连接 | ⋈ | Bowtie | 二元 | 两个关系 | 一个关系 |
| 除 | ÷ | Division | 二元 | 两个关系 | 一个关系 |
示例关系
后续章节将使用以下示例关系来说明各种运算:
学生表 Student: 课程表 Course:
┌─────┬──────┬─────┐ ┌─────┬──────────┬─────┐
│ Sno │ Name │ Age │ │ Cno │ Cname │ Credit│
├─────┼──────┼─────┤ ├─────┼──────────┼─────┤
│ S1 │ 张三 │ 20 │ │ C1 │ 数据库 │ 4 │
│ S2 │ 李四 │ 21 │ │ C2 │ 数学 │ 3 │
│ S3 │ 王五 │ 19 │ │ C3 │ 英语 │ 2 │
└─────┴──────┴─────┘ └─────┴──────────┴─────┘
选课表 SC(学生-课程关系):
┌─────┬─────┬───────┐
│ Sno │ Cno │ Grade │
├─────┼─────┼───────┤
│ S1 │ C1 │ 90 │
│ S1 │ C2 │ 85 │
│ S2 │ C1 │ 88 │
│ S2 │ C3 │ 78 │
│ S3 │ C2 │ 92 │
└─────┴─────┴───────┘
第二章 传统集合运算
传统集合运算来源于数学中的集合论,是关系代数的基础运算。这些运算要求参与运算的两个关系必须具有相同的目(属性个数相同,对应属性的域相容)。
2.1 并运算(Union)
2.1.1 定义
并运算 是将两个关系的所有元组合并成一个关系,同时去除重复元组。
通俗理解:
把两个表的数据"合并"在一起,相同的行只保留一份。
就像把两个班级的学生名单合并成一个年级名单。
运算前提(并相容条件):
- R和S的属性个数相同(目相同)
- 对应属性的域相同(或可相互转换)
2.1.2 符号表示
R ∪ S = { t | t ∈ R ∨ t ∈ S }
读作:R并S等于所有属于R或属于S的元组t的集合
2.1.3 性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 交换律 | R ∪ S = S ∪ R | 顺序不影响结果 |
| 结合律 | (R ∪ S) ∪ T = R ∪ (S ∪ T) | 可以任意组合 |
| 幂等律 | R ∪ R = R | 自己并自己还是自己 |
| 零元素 | R ∪ ∅ = R | 并上空集不变 |
2.1.4 示例
关系R(班级A学生): 关系S(班级B学生):
┌─────┬──────┬─────┐ ┌─────┬──────┬─────┐
│ Sno │ Name │ Age │ │ Sno │ Name │ Age │
├─────┼──────┼─────┤ ├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │ │ S2 │ 李四 │ 21 │
│ S2 │ 李四 │ 21 │ │ S4 │ 赵六 │ 20 │
│ S3 │ 王五 │ 19 │ │ S5 │ 孙七 │ 22 │
└─────┴──────┴─────┘ └─────┴──────┴─────┘
R ∪ S(合并两个班级):
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │
│ S2 │ 李四 │ 21 │ ← S2李四只出现一次(去重)
│ S3 │ 王五 │ 19 │
│ S4 │ 赵六 │ 20 │
│ S5 │ 孙七 │ 22 │
└─────┴──────┴─────┘
结果:5个元组(不是6个,因为S2重复)
对应SQL:
sql
SELECT * FROM R
UNION
SELECT * FROM S;
2.2 交运算(Intersection)
2.2.1 定义
交运算 是取两个关系的公共元组,即同时出现在两个关系中的元组。
通俗理解:
找出两个表中"完全相同"的行。
就像找出同时参加了两个社团的学生。
运算前提: R和S必须并相容
2.2.2 符号表示
R ∩ S = { t | t ∈ R ∧ t ∈ S }
读作:R交S等于所有既属于R又属于S的元组t的集合
2.2.3 性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 交换律 | R ∩ S = S ∩ R | 顺序不影响结果 |
| 结合律 | (R ∩ S) ∩ T = R ∩ (S ∩ T) | 可以任意组合 |
| 幂等律 | R ∩ R = R | 自己交自己还是自己 |
| 零元素 | R ∩ ∅ = ∅ | 交上空集为空 |
2.2.4 可用差运算表示
交运算不是基本运算,可以用差运算表示:
R ∩ S = R - (R - S)
推导:
R - S = R中有但S中没有的元组
R - (R-S) = R中去掉"R有S没有的"= R和S都有的 = R ∩ S
2.2.5 示例
关系R: 关系S:
┌─────┬──────┬─────┐ ┌─────┬──────┬─────┐
│ Sno │ Name │ Age │ │ Sno │ Name │ Age │
├─────┼──────┼─────┤ ├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │ │ S2 │ 李四 │ 21 │
│ S2 │ 李四 │ 21 │ │ S4 │ 赵六 │ 20 │
│ S3 │ 王五 │ 19 │ │ S5 │ 孙七 │ 22 │
└─────┴──────┴─────┘ └─────┴──────┴─────┘
R ∩ S(两个班级都有的学生):
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S2 │ 李四 │ 21 │ ← 只有李四同时在两个班级
└─────┴──────┴─────┘
结果:1个元组
对应SQL:
sql
SELECT * FROM R
INTERSECT
SELECT * FROM S;
2.3 差运算(Difference)
2.3.1 定义
差运算 是从关系R中去除也在关系S中出现的元组,保留R中独有的元组。
通俗理解:
找出只在第一个表中有,第二个表中没有的行。
就像找出只参加了社团A但没参加社团B的学生。
运算前提: R和S必须并相容
2.3.2 符号表示
R - S = { t | t ∈ R ∧ t ∉ S }
读作:R减S等于所有属于R但不属于S的元组t的集合
2.3.3 性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 不满足交换律 | R - S ≠ S - R | 顺序会影响结果! |
| 不满足结合律 | (R - S) - T ≠ R - (S - T) | 不能任意组合 |
| 零元素 | R - ∅ = R | 减去空集不变 |
| 自反 | R - R = ∅ | 自己减自己为空 |
注意:差运算是五种基本运算之一,也是唯一不满足交换律的集合运算!
2.3.4 示例
关系R: 关系S:
┌─────┬──────┬─────┐ ┌─────┬──────┬─────┐
│ Sno │ Name │ Age │ │ Sno │ Name │ Age │
├─────┼──────┼─────┤ ├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │ │ S2 │ 李四 │ 21 │
│ S2 │ 李四 │ 21 │ │ S4 │ 赵六 │ 20 │
│ S3 │ 王五 │ 19 │ │ S5 │ 孙七 │ 22 │
└─────┴──────┴─────┘ └─────┴──────┴─────┘
R - S(只在班级A不在班级B的学生):
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │
│ S3 │ 王五 │ 19 │
└─────┴──────┴─────┘
S - R(只在班级B不在班级A的学生):
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S4 │ 赵六 │ 20 │
│ S5 │ 孙七 │ 22 │
└─────┴──────┴─────┘
注意:R - S ≠ S - R!
对应SQL:
sql
SELECT * FROM R
EXCEPT -- 或 MINUS(Oracle语法)
SELECT * FROM S;
2.4 笛卡尔积(Cartesian Product)
2.4.1 定义
笛卡尔积 是将两个关系的每一个元组进行所有可能的组合。
通俗理解:
把两个表的每一行都两两配对,生成所有可能的组合。
就像学生表和课程表的笛卡尔积 = 每个学生配每门课程。
结果特点:
- 若R有n个属性、m₁个元组
- 若S有k个属性、m₂个元组
- R × S 有 n+k个属性 、m₁ × m₂个元组
2.4.2 符号表示
R × S = { t₁t₂ | t₁ ∈ R ∧ t₂ ∈ S }
读作:R叉乘S等于R中每个元组与S中每个元组连接而成的新元组的集合
2.4.3 性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 交换律 | R × S ≈ S × R | 元组相同,属性顺序不同 |
| 结合律 | (R × S) × T = R × (S × T) | 可以任意组合 |
| 分配律 | R × (S ∪ T) = (R × S) ∪ (R × T) | 对并运算分配 |
2.4.4 示例
关系R(学生): 关系S(课程):
┌─────┬──────┐ ┌─────┬──────┐
│ Sno │ Name │ │ Cno │ Cname│
├─────┼──────┤ ├─────┼──────┤
│ S1 │ 张三 │ │ C1 │ 数据库│
│ S2 │ 李四 │ │ C2 │ 数学 │
└─────┴──────┘ └─────┴──────┘
2个元组 2个元组
R × S(笛卡尔积):
┌─────┬──────┬─────┬──────┐
│ Sno │ Name │ Cno │ Cname│
├─────┼──────┼─────┼──────┤
│ S1 │ 张三 │ C1 │ 数据库│ ← S1配C1
│ S1 │ 张三 │ C2 │ 数学 │ ← S1配C2
│ S2 │ 李四 │ C1 │ 数据库│ ← S2配C1
│ S2 │ 李四 │ C2 │ 数学 │ ← S2配C2
└─────┴──────┴─────┴──────┘
结果:2+2=4个属性,2×2=4个元组
重要说明:
笛卡尔积本身很少单独使用,因为结果包含大量无意义的组合。它通常与选择运算 结合使用来实现连接运算:
连接 = 笛卡尔积 + 选择
自然连接 R ⋈ S = σ(等值条件)(R × S)
对应SQL:
sql
SELECT * FROM R, S; -- 隐式笛卡尔积
SELECT * FROM R CROSS JOIN S; -- 显式笛卡尔积
本章小结
传统集合运算总结:
┌─────────────┬────────┬───────────────────────────────────────┐
│ 运算 │ 符号 │ 要点 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 并 │ ∪ │ 合并去重,需并相容 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 交 │ ∩ │ 取公共,可用差表示 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 差 │ - │ 取独有,不满足交换律! │
├─────────────┼────────┼───────────────────────────────────────┤
│ 笛卡尔积 │ × │ 元组数相乘,属性数相加 │
└─────────────┴────────┴───────────────────────────────────────┘
基本运算:并、差、笛卡尔积(交可以用差表示)
第三章 专门关系运算
专门关系运算是专门为关系数据库设计的运算,包括选择、投影、连接和除法。这些运算是关系代数的核心,也是SQL查询的理论基础。
3.1 选择运算(Selection / Restriction)
3.1.1 定义
选择运算 是从关系R中选取满足指定条件的元组,形成一个新的关系。
通俗理解:
选择就是"筛选行",保留满足条件的行,去掉不满足条件的行。
就像在学生表中筛选出"年龄大于20岁"的学生。
┌──────────────────────────────────────────────────────────────┐
│ 选择运算的效果:水平切分(行选择) │
├──────────────────────────────────────────────────────────────┤
│ │
│ 原始关系R: 选择后 σ_F(R): │
│ ┌─────┬─────┬─────┐ ┌─────┬─────┬─────┐ │
│ │ A │ B │ C │ │ A │ B │ C │ │
│ ├─────┼─────┼─────┤ ├─────┼─────┼─────┤ │
│ │ ... │ ... │ ... │ → │ ... │ ... │ ... │ ← 满足条件 │
│ │ ... │ ... │ ... │ │ ... │ ... │ ... │ ← 满足条件 │
│ │ ... │ ... │ ... │ └─────┴─────┴─────┘ │
│ └─────┴─────┴─────┘ │
│ (列不变,行减少) │
└──────────────────────────────────────────────────────────────┘
3.1.2 符号表示
σ_F(R) = { t | t ∈ R ∧ F(t) = true }
读作:Sigma F of R
含义:从关系R中选择满足条件F的所有元组t
其中:
- σ(sigma)是选择运算符
- F 是选择条件(谓词)
- R 是关系名
3.1.3 条件表达式F
选择条件F由以下元素构成:
| 类型 | 运算符 | 含义 |
|---|---|---|
| 比较运算符 | >, <, =, ≥, ≤, ≠ | 属性与常量或属性比较 |
| 逻辑运算符 | ∧(AND),∨(OR),¬(NOT) | 组合多个条件 |
条件格式:
- 简单条件:
属性 θ 常量或属性 θ 属性 - 复合条件:使用∧、∨、¬组合简单条件
3.1.4 性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 级联选择 | σ_F1(σ_F2®) = σ_F1∧F2® | 多个选择可合并 |
| 选择交换 | σ_F1(σ_F2®) = σ_F2(σ_F1®) | 顺序可交换 |
| 选择与投影 | σ_F(π_A®) = π_A(σ_F®)(当F只涉及A中的属性) | 条件允许时可交换 |
| 选择与笛卡尔积 | σ_F(R × S) = σ_F® × S(当F只涉及R的属性) | 可下推到单个关系 |
3.1.5 示例
学生表 Student:
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │
│ S2 │ 李四 │ 21 │
│ S3 │ 王五 │ 19 │
│ S4 │ 赵六 │ 22 │
└─────┴──────┴─────┘
查询1:选择年龄大于20的学生
σ_Age>20(Student)
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S2 │ 李四 │ 21 │
│ S4 │ 赵六 │ 22 │
└─────┴──────┴─────┘
查询2:选择年龄大于20且学号以S开头的学生
σ_Age>20 ∧ Sno='S2'(Student)
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S2 │ 李四 │ 21 │
└─────┴──────┴─────┘
对应SQL:
sql
-- 查询1
SELECT * FROM Student WHERE Age > 20;
-- 查询2
SELECT * FROM Student WHERE Age > 20 AND Sno = 'S2';
3.2 投影运算(Projection)
3.2.1 定义
投影运算 是从关系R中选取指定的属性列,形成一个新的关系。
通俗理解:
投影就是"选择列",只保留需要的列,其他列去掉。
同时会自动去除结果中的重复元组。
┌──────────────────────────────────────────────────────────────┐
│ 投影运算的效果:垂直切分(列选择) │
├──────────────────────────────────────────────────────────────┤
│ │
│ 原始关系R: 投影后 π_A,B(R): │
│ ┌─────┬─────┬─────┐ ┌─────┬─────┐ │
│ │ A │ B │ C │ │ A │ B │ ← 只保留A、B列 │
│ ├─────┼─────┼─────┤ ├─────┼─────┤ │
│ │ ... │ ... │ ... │ → │ ... │ ... │ │
│ │ ... │ ... │ ... │ │ ... │ ... │ │
│ │ ... │ ... │ ... │ └─────┴─────┘ │
│ └─────┴─────┴─────┘ │
│ (行可能减少-去重,列减少) │
└──────────────────────────────────────────────────────────────┘
3.2.2 符号表示
π_A(R) = { t[A] | t ∈ R }
读作:Pi A of R
含义:从关系R中选择属性集A对应的列
其中:
- π(pi)是投影运算符
- A 是属性名列表(如 A₁, A₂, ..., Aₙ)
- t[A] 表示元组t在属性集A上的分量
3.2.3 性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 级联投影 | π_A(π_B®) = π_A®,其中A ⊆ B | 投影的投影等于小的投影 |
| 投影交换 | π_A(R ∪ S) = π_A® ∪ π_A(S) | 对并运算分配 |
重要说明: 投影会自动去除重复元组,这是关系代数的基本要求(关系是集合)。
3.2.4 示例
学生表 Student:
┌─────┬──────┬─────┐
│ Sno │ Name │ Age │
├─────┼──────┼─────┤
│ S1 │ 张三 │ 20 │
│ S2 │ 李四 │ 21 │
│ S3 │ 王五 │ 19 │
│ S4 │ 张三 │ 22 │ ← 注意:有两个张三
└─────┴──────┴─────┘
查询1:投影学号和姓名
π_Sno,Name(Student)
┌─────┬──────┐
│ Sno │ Name │
├─────┼──────┤
│ S1 │ 张三 │
│ S2 │ 李四 │
│ S3 │ 王五 │
│ S4 │ 张三 │
└─────┴──────┘
查询2:只投影姓名
π_Name(Student)
┌──────┐
│ Name │
├──────┤
│ 张三 │ ← 两个张三只保留一个!
│ 李四 │
│ 王五 │
└──────┘
结果只有3个元组(去重)
对应SQL:
sql
-- 查询1
SELECT Sno, Name FROM Student;
-- 查询2(去重)
SELECT DISTINCT Name FROM Student;
注意: SQL中需要使用DISTINCT来去重,而关系代数中投影自动去重。
3.3 连接运算(Join)
连接是关系代数中最重要的运算,用于关联两个关系。
3.3.1 θ连接(Theta Join)
定义
θ连接是从两个关系的笛卡尔积中选取满足特定条件的元组。
R ⋈_{AθB} S = σ_{AθB}(R × S)
其中θ是比较运算符(>、<、=、≥、≤、≠)
通俗理解
θ连接 = 笛卡尔积 + 选择
先把两个表所有组合列出来(笛卡尔积),
再筛选出满足条件的行(选择)。
示例
关系R: 关系S:
┌────┬────┐ ┌────┬────┐
│ A │ B │ │ C │ D │
├────┼────┤ ├────┼────┤
│ 1 │ 2 │ │ 2 │ x │
│ 3 │ 4 │ │ 4 │ y │
└────┴────┘ └────┴────┘
R ⋈_{B<C} S(B小于C的连接):
┌────┬────┬────┬────┐
│ A │ B │ C │ D │
├────┼────┼────┼────┤
│ 1 │ 2 │ 4 │ y │ ← 2 < 4
└────┴────┴────┴────┘
3.3.2 等值连接(Equi-Join)
定义
等值连接是θ为等号(=)的θ连接。
R ⋈_{A=B} S = σ_{A=B}(R × S)
特点
- θ为等号
- 结果中保留两个连接属性(都保留)
示例
关系R: 关系S:
┌────┬────┐ ┌────┬────┐
│ A │ B │ │ B │ C │
├────┼────┤ ├────┼────┤
│ 1 │ 2 │ │ 2 │ x │
│ 3 │ 4 │ │ 4 │ y │
└────┴────┘ └────┴────┘
R ⋈_{R.B=S.B} S(等值连接):
┌────┬─────┬─────┬────┐
│ A │ R.B │ S.B │ C │
├────┼─────┼─────┼────┤
│ 1 │ 2 │ 2 │ x │
│ 3 │ 4 │ 4 │ y │
└────┴─────┴─────┴────┘
注意:B列出现两次!
3.3.3 自然连接(Natural Join)
定义
自然连接 是等值连接的特殊情况:
-
自动在所有同名属性上进行等值连接
-
结果中去除重复的连接属性列
R ⋈ S
不需要指定连接条件,自动使用同名属性
通俗理解
自然连接 = 等值连接 + 去除重复列
自动找两个表的同名列进行匹配,
结果中同名列只保留一份。
性质
| 性质 | 表达式 | 说明 |
|---|---|---|
| 交换律 | R ⋈ S = S ⋈ R | 顺序不影响结果 |
| 结合律 | (R ⋈ S) ⋈ T = R ⋈ (S ⋈ T) | 可以任意组合 |
示例
学生表 Student: 选课表 SC:
┌─────┬──────┬─────┐ ┌─────┬─────┬───────┐
│ Sno │ Name │ Age │ │ Sno │ Cno │ Grade │
├─────┼──────┼─────┤ ├─────┼─────┼───────┤
│ S1 │ 张三 │ 20 │ │ S1 │ C1 │ 90 │
│ S2 │ 李四 │ 21 │ │ S1 │ C2 │ 85 │
│ S3 │ 王五 │ 19 │ │ S2 │ C1 │ 88 │
└─────┴──────┴─────┘ └─────┴─────┴───────┘
Student ⋈ SC(自然连接):
┌─────┬──────┬─────┬─────┬───────┐
│ Sno │ Name │ Age │ Cno │ Grade │
├─────┼──────┼─────┼─────┼───────┤
│ S1 │ 张三 │ 20 │ C1 │ 90 │
│ S1 │ 张三 │ 20 │ C2 │ 85 │
│ S2 │ 李四 │ 21 │ C1 │ 88 │
└─────┴──────┴─────┴─────┴───────┘
说明:
- 在同名属性Sno上进行等值连接
- Sno列只出现一次(去重)
- S3没有选课记录,所以不在结果中
对应SQL:
sql
-- 自然连接
SELECT * FROM Student NATURAL JOIN SC;
-- 等价的显式连接
SELECT Student.Sno, Name, Age, Cno, Grade
FROM Student INNER JOIN SC ON Student.Sno = SC.Sno;
3.3.4 连接类型对比
连接类型关系:
┌─────────────────────────────────────────────────────────────────┐
│ 连接类型层次 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ θ连接 ← 最通用(任意比较条件) │
│ ↓ │
│ 等值连接 ← θ为等号的θ连接 │
│ ↓ │
│ 自然连接 ← 等值连接 + 去重复列 + 自动匹配同名列│
│ │
└─────────────────────────────────────────────────────────────────┘
3.4 除运算(Division)
3.4.1 定义
除运算 用于查询"与S中所有元组都有关系"的R中的数据。
通俗理解:
除法用于回答"全部"、"所有"类型的问题。
例如:"查询选修了所有课程的学生"
设:
- R(X, Y):关系R有属性集X和Y
- S(Y):关系S只有属性集Y(Y是R和S的公共属性)
- R ÷ S:结果只包含X属性
3.4.2 符号表示
R ÷ S = { t[X] | t ∈ R ∧ π_Y(S) ⊆ Y_x }
其中 Y_x = { t[Y] | t ∈ R ∧ t[X] = x }
通俗解释:
- Y_x 是R中与x相关联的所有Y值的集合
- 如果S中的所有Y值都在Y_x中,则x在结果中
3.4.3 等价表示(用基本运算)
R ÷ S = π_X(R) - π_X((π_X(R) × S) - R)
推导过程:
1. π_X(R):R中所有可能的X值
2. π_X(R) × S:X与S的所有组合("应该有"的所有关系)
3. (π_X(R) × S) - R:R中缺少的关系
4. π_X(...):缺少关系的X值
5. π_X(R) - ...:去掉"缺少关系的X"= 与S完全匹配的X
3.4.4 适用场景
除法运算适用于包含以下关键词的查询:
- "所有"
- "全部"
- "每一个"
- "至少包含...中的所有"
3.4.5 示例
选课表 SC: 课程表 AllCourses:
┌─────┬─────┐ ┌─────┐
│ Sno │ Cno │ │ Cno │
├─────┼─────┤ ├─────┤
│ S1 │ C1 │ │ C1 │
│ S1 │ C2 │ │ C2 │
│ S1 │ C3 │ │ C3 │
│ S2 │ C1 │ └─────┘
│ S2 │ C2 │
│ S3 │ C1 │
│ S3 │ C3 │
└─────┴─────┘
问题:查询选修了所有课程(C1, C2, C3)的学生
SC ÷ AllCourses = ?
分析:
- S1选了C1, C2, C3(全部3门)✓
- S2选了C1, C2(缺C3)✗
- S3选了C1, C3(缺C2)✗
结果:
┌─────┐
│ Sno │
├─────┤
│ S1 │ ← 只有S1选了所有课程
└─────┘
验证过程:
步骤1:π_Sno(SC) = {S1, S2, S3}
步骤2:π_Sno(SC) × AllCourses =
{(S1,C1), (S1,C2), (S1,C3),
(S2,C1), (S2,C2), (S2,C3),
(S3,C1), (S3,C2), (S3,C3)}
步骤3:(π_Sno(SC) × AllCourses) - SC =
{(S2,C3), (S3,C2)} ← S2缺C3,S3缺C2
步骤4:π_Sno(...) = {S2, S3} ← 有缺失的学生
步骤5:π_Sno(SC) - ... = {S1} ← 没有缺失的学生 = 结果
对应SQL:
sql
-- 方法1:使用NOT EXISTS
SELECT DISTINCT Sno
FROM SC SC1
WHERE NOT EXISTS (
SELECT Cno FROM AllCourses
WHERE Cno NOT IN (
SELECT Cno FROM SC SC2 WHERE SC2.Sno = SC1.Sno
)
);
-- 方法2:使用COUNT
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(DISTINCT Cno) = (SELECT COUNT(*) FROM AllCourses);
本章小结
专门关系运算总结:
┌─────────────┬────────┬───────────────────────────────────────┐
│ 运算 │ 符号 │ 要点 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 选择 │ σ │ 水平切分,按条件选行 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 投影 │ π │ 垂直切分,选列并去重 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 连接 │ ⋈ │ 关联两表,自然连接最常用 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 除法 │ ÷ │ "全部"类型查询 │
└─────────────┴────────┴───────────────────────────────────────┘
基本运算:选择、投影(连接和除法可用基本运算表示)
最重要:选择 + 投影 + 自然连接 = 90%的查询需求
第四章 扩展关系运算
扩展关系运算是在基本关系代数基础上发展出来的,用于处理更复杂的实际需求。这些运算在现代SQL中都有对应实现。
4.1 外连接(Outer Join)
普通连接(内连接)只保留匹配的元组,而外连接可以保留不匹配的元组。
通俗理解:
内连接:只取两边都有对应的数据
外连接:保留一边或两边不匹配的数据,用NULL填充
4.1.1 左外连接(Left Outer Join)
定义: 保留左侧关系R的所有元组,右侧S中无匹配的用NULL填充
符号: R ⟕ S
学生表 Student: 选课表 SC:
┌─────┬──────┐ ┌─────┬─────┐
│ Sno │ Name │ │ Sno │ Cno │
├─────┼──────┤ ├─────┼─────┤
│ S1 │ 张三 │ │ S1 │ C1 │
│ S2 │ 李四 │ │ S1 │ C2 │
│ S3 │ 王五 │ │ S2 │ C1 │
└─────┴──────┘ └─────┴─────┘
Student ⟕ SC(左外连接):
┌─────┬──────┬─────┐
│ Sno │ Name │ Cno │
├─────┼──────┼─────┤
│ S1 │ 张三 │ C1 │
│ S1 │ 张三 │ C2 │
│ S2 │ 李四 │ C1 │
│ S3 │ 王五 │ NULL│ ← S3没选课,Cno为NULL
└─────┴──────┴─────┘
保留了所有学生,包括未选课的S3
对应SQL:
sql
SELECT * FROM Student LEFT OUTER JOIN SC ON Student.Sno = SC.Sno;
4.1.2 右外连接(Right Outer Join)
定义: 保留右侧关系S的所有元组,左侧R中无匹配的用NULL填充
符号: R ⟖ S
Student ⟖ SC(右外连接):
保留SC中的所有记录,Student中无匹配的用NULL填充
对应SQL:
sql
SELECT * FROM Student RIGHT OUTER JOIN SC ON Student.Sno = SC.Sno;
4.1.3 全外连接(Full Outer Join)
定义: 保留两侧关系的所有元组,任一侧无匹配的都用NULL填充
符号: R ⟗ S
R ⟗ S = (R ⟕ S) ∪ (R ⟖ S)
全外连接 = 左外连接 ∪ 右外连接
对应SQL:
sql
SELECT * FROM Student FULL OUTER JOIN SC ON Student.Sno = SC.Sno;
外连接对比图
┌─────────────────────────────────────────────────────────────────┐
│ 外连接类型对比 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 内连接 ⋈: R ∩ S(只取交集部分) │
│ │
│ 左外连接 ⟕: R 全部 + S 中匹配的部分 │
│ │
│ 右外连接 ⟖: R 中匹配的部分 + S 全部 │
│ │
│ 全外连接 ⟗: R 全部 + S 全部(并集) │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ R: │ ████████ │ │ ████████ │ :S │
│ │ ┌─────┼───┼─────┐ │ │
│ │ │ │ │ │ │ │
│ │ │ 内连│接 │ │ │ │
│ │ │ │ │ │ │ │
│ │ └─────┼───┼─────┘ │ │
│ │ 左外 │ │ 右外 │ │
│ └──────────┘ └──────────┘ │
│ └─────────────────────┘ │
│ 全外连接 │
└─────────────────────────────────────────────────────────────────┘
4.2 半连接(Semi-Join)
定义: 返回R中与S能连接的元组,但只保留R的属性
符号: R ⋉ S
R ⋉ S = π_R(R ⋈ S)
只返回R中能与S匹配的行,不包含S的任何属性
示例:
Student ⋉ SC = 返回有选课记录的学生(只保留Student的列)
结果:
┌─────┬──────┐
│ Sno │ Name │
├─────┼──────┤
│ S1 │ 张三 │
│ S2 │ 李四 │
└─────┴──────┘
(S3没有选课记录,不在结果中)
对应SQL:
sql
SELECT DISTINCT Student.*
FROM Student
WHERE EXISTS (SELECT 1 FROM SC WHERE SC.Sno = Student.Sno);
4.3 反连接(Anti-Join)
定义: 返回R中与S不能连接的元组
符号: R ▷ S
R ▷ S = R - (R ⋉ S)
返回R中无法与S匹配的行
示例:
Student ▷ SC = 返回没有选课记录的学生
结果:
┌─────┬──────┐
│ Sno │ Name │
├─────┼──────┤
│ S3 │ 王五 │ ← 只有S3没选课
└─────┴──────┘
对应SQL:
sql
SELECT * FROM Student
WHERE NOT EXISTS (SELECT 1 FROM SC WHERE SC.Sno = Student.Sno);
4.4 聚集运算(Aggregation)
定义: 对关系的某属性值进行统计计算
符号: ℱ_F® 或 G_F®
常用聚集函数:
| 函数 | 含义 | 示例 |
|---|---|---|
| COUNT | 计数 | COUNT(*) 或 COUNT(A) |
| SUM | 求和 | SUM(Grade) |
| AVG | 平均值 | AVG(Grade) |
| MAX | 最大值 | MAX(Grade) |
| MIN | 最小值 | MIN(Grade) |
示例:
选课表 SC:
┌─────┬─────┬───────┐
│ Sno │ Cno │ Grade │
├─────┼─────┼───────┤
│ S1 │ C1 │ 90 │
│ S1 │ C2 │ 85 │
│ S2 │ C1 │ 88 │
│ S2 │ C3 │ 78 │
└─────┴─────┴───────┘
ℱ_COUNT(*)(SC) = 4 -- 总记录数
ℱ_AVG(Grade)(SC) = 85.25 -- 平均成绩
ℱ_MAX(Grade)(SC) = 90 -- 最高成绩
对应SQL:
sql
SELECT COUNT(*), AVG(Grade), MAX(Grade) FROM SC;
4.5 分组运算(Grouping)
定义: 按指定属性分组,然后对每组应用聚集函数
符号: γ_A,F® 或 G A ℱ F®
其中:
- A 是分组属性
- F 是聚集函数
示例:
选课表 SC:
┌─────┬─────┬───────┐
│ Sno │ Cno │ Grade │
├─────┼─────┼───────┤
│ S1 │ C1 │ 90 │
│ S1 │ C2 │ 85 │
│ S2 │ C1 │ 88 │
│ S2 │ C3 │ 78 │
└─────┴─────┴───────┘
按学生分组,计算每个学生的平均成绩:
γ_Sno, AVG(Grade)(SC)
结果:
┌─────┬───────────┐
│ Sno │ AVG(Grade)│
├─────┼───────────┤
│ S1 │ 87.5 │ ← (90+85)/2
│ S2 │ 83.0 │ ← (88+78)/2
└─────┴───────────┘
对应SQL:
sql
SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno;
4.6 重命名运算(Rename)
定义: 为关系或属性指定新名称
符号: ρ_S(A1,A2,...)® 或 ρ_S®
用途:
- 自连接时区分同一关系的两个实例
- 使表达式更清晰
示例:
查询所有学生对(不同学生的两两组合)
需要自连接,使用重命名区分:
ρ_R1(Student) ⋈_{R1.Sno < R2.Sno} ρ_R2(Student)
对应SQL:
sql
SELECT R1.*, R2.*
FROM Student R1, Student R2
WHERE R1.Sno < R2.Sno;
本章小结
扩展关系运算总结:
┌─────────────┬────────┬───────────────────────────────────────┐
│ 运算 │ 符号 │ 要点 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 左外连接 │ ⟕ │ 保留左表全部,右表无匹配用NULL │
├─────────────┼────────┼───────────────────────────────────────┤
│ 右外连接 │ ⟖ │ 保留右表全部,左表无匹配用NULL │
├─────────────┼────────┼───────────────────────────────────────┤
│ 全外连接 │ ⟗ │ 保留两表全部 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 半连接 │ ⋉ │ 只返回能匹配的左表元组 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 反连接 │ ▷ │ 只返回不能匹配的左表元组 │
├─────────────┼────────┼───────────────────────────────────────┤
│ 聚集 │ ℱ │ COUNT, SUM, AVG, MAX, MIN │
├─────────────┼────────┼───────────────────────────────────────┤
│ 分组 │ γ │ GROUP BY + 聚集函数 │
└─────────────┴────────┴───────────────────────────────────────┘
第五章 运算符优先级与表达式
理解运算符优先级和表达式构造规则,对于正确书写和阅读关系代数表达式至关重要。
5.1 运算符优先级
优先级规则
关系代数运算符的优先级从高到低:
┌─────────────────────────────────────────────────────────────────┐
│ 运算符优先级(从高到低) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 优先级 1(最高): │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 括号 () │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 优先级 2: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 一元运算符:σ(选择)、π(投影)、ρ(重命名) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 优先级 3: │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 笛卡尔积 ×、各种连接 ⋈ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 优先级 4(最低): │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 集合运算:∪(并)、∩(交)、-(差) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
优先级表
| 优先级 | 运算符 | 类型 | 结合性 |
|---|---|---|---|
| 1 | () | 括号 | - |
| 2 | σ, π, ρ | 一元 | 右结合 |
| 3 | ×, ⋈, ÷ | 二元 | 左结合 |
| 4 | ∪, ∩, - | 二元 | 左结合 |
优先级示例
表达式:π_A(σ_B>5(R ⋈ S)) ∪ T
解析顺序:
1. R ⋈ S -- 先执行连接
2. σ_B>5(...) -- 再执行选择
3. π_A(...) -- 然后执行投影
4. ... ∪ T -- 最后执行并运算
等价于:(π_A(σ_B>5((R ⋈ S)))) ∪ T
5.2 关系代数表达式
表达式的构造规则
关系代数表达式由以下规则递归定义:
基本表达式:
1. 关系名R是一个表达式(每个关系本身就是表达式)
2. 常量关系是一个表达式
归纳规则:
如果E₁和E₂是表达式,则以下也是表达式:
3. E₁ ∪ E₂ -- 并
4. E₁ - E₂ -- 差
5. E₁ × E₂ -- 笛卡尔积
6. σ_F(E₁) -- 选择
7. π_A(E₁) -- 投影
8. E₁ ⋈ E₂ -- 连接
9. ρ_X(E₁) -- 重命名
表达式树
复杂的关系代数表达式可以用表达式树表示:
查询:查询选修了数据库课程且成绩大于85分的学生姓名
π_Name(σ_Cname='数据库' ∧ Grade>85(Student ⋈ SC ⋈ Course))
表达式树:
π_Name
│
σ_Cname='数据库' ∧ Grade>85
│
⋈
/ \
⋈ Course
/ \
Student SC
执行顺序(自底向上):
1. Student ⋈ SC
2. 结果 ⋈ Course
3. σ_Cname='数据库' ∧ Grade>85(结果)
4. π_Name(结果)
5.3 查询优化基础
数据库优化器使用关系代数的等价变换规则来优化查询。
等价变换规则
| 规则 | 表达式 | 说明 |
|---|---|---|
| 选择串联 | σ_F1∧F2® = σ_F1(σ_F2®) | 选择可拆分 |
| 选择交换 | σ_F1(σ_F2®) = σ_F2(σ_F1®) | 选择顺序可换 |
| 投影串联 | π_A(π_B®) = π_A®,A⊆B | 投影可合并 |
| 选择与投影 | π_A(σ_F®) = σ_F(π_A®),F只涉及A | 选择投影可换 |
| 选择与笛卡尔积 | σ_F(R × S) = σ_F® × S,F只涉及R | 选择下推 |
| 投影与笛卡尔积 | π_{A∪B}(R × S) = π_A® × π_B(S) | 投影下推 |
| 连接交换 | R ⋈ S = S ⋈ R | 连接可交换 |
| 连接结合 | (R ⋈ S) ⋈ T = R ⋈ (S ⋈ T) | 连接可结合 |
优化策略
核心思想:尽早减少数据量
┌─────────────────────────────────────────────────────────────────┐
│ 查询优化基本策略 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 策略1:尽早执行选择(Selection Push-Down) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 选择运算可以大幅减少元组数 │ │
│ │ • 应尽可能将选择操作下推到表达式树的底部 │ │
│ │ • 例如:σ_F(R × S) → σ_F(R) × S(当F只涉及R) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 策略2:尽早执行投影(Projection Push-Down) │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 投影可以减少每个元组的宽度 │ │
│ │ • 应尽可能将投影操作下推 │ │
│ │ • 去除后续不需要的属性 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 策略3:避免笛卡尔积 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 笛卡尔积产生最大的结果集 │ │
│ │ • 尽可能用连接代替笛卡尔积+选择 │ │
│ │ • σ_F(R × S) → R ⋈_F S │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 策略4:合并连续的选择和投影 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ • 多个选择合并:σ_F1(σ_F2(R)) → σ_F1∧F2(R) │ │
│ │ • 多个投影合并:π_A(π_B(R)) → π_A(R) │ │
│ │ • 减少中间结果的生成次数 │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
优化示例
原始查询:
π_Name(σ_Cname='数据库' ∧ Grade>85(Student ⋈ SC ⋈ Course))
优化前的表达式树:
π_Name
│
σ_Cname='数据库' ∧ Grade>85
│
⋈
/ \
⋈ Course
/ \
Student SC
优化后的表达式树(选择下推):
π_Name
│
⋈
/ \
⋈ σ_Cname='数据库'(Course)
/ \
Student σ_Grade>85(SC)
优化效果:
- 先过滤SC中成绩>85的记录
- 先过滤Course中数据库课程
- 再进行连接,中间结果更小
本章小结
运算符优先级与表达式要点:
┌─────────────────────────────────────────────────────────────────┐
│ │
│ 优先级:括号 > 一元(σ,π) > 连接(⋈,×) > 集合(∪,∩,-) │
│ │
│ 表达式树:从叶子向根执行 │
│ │
│ 优化核心: │
│ 1. 选择尽早执行(减少行数) │
│ 2. 投影尽早执行(减少列数) │
│ 3. 避免笛卡尔积 │
│ 4. 合并连续操作 │
│ │
└─────────────────────────────────────────────────────────────────┘
第六章 关系代数与SQL对照
关系代数是SQL的理论基础,理解两者的对应关系有助于深入理解数据库查询。
6.1 运算符对照表
完整对照表
| 关系代数 | 符号 | SQL语法 | 示例 |
|---|---|---|---|
| 并 | R ∪ S | UNION | SELECT * FROM R UNION SELECT * FROM S |
| 交 | R ∩ S | INTERSECT | SELECT * FROM R INTERSECT SELECT * FROM S |
| 差 | R - S | EXCEPT / MINUS | SELECT * FROM R EXCEPT SELECT * FROM S |
| 笛卡尔积 | R × S | CROSS JOIN | SELECT * FROM R CROSS JOIN S |
| 选择 | σ_F® | WHERE | SELECT * FROM R WHERE F |
| 投影 | π_A® | SELECT A | SELECT A FROM R |
| 自然连接 | R ⋈ S | NATURAL JOIN | SELECT * FROM R NATURAL JOIN S |
| θ连接 | R ⋈_θ S | JOIN ON | SELECT * FROM R JOIN S ON θ |
| 左外连接 | R ⟕ S | LEFT OUTER JOIN | SELECT * FROM R LEFT JOIN S ON ... |
| 右外连接 | R ⟖ S | RIGHT OUTER JOIN | SELECT * FROM R RIGHT JOIN S ON ... |
| 全外连接 | R ⟗ S | FULL OUTER JOIN | SELECT * FROM R FULL JOIN S ON ... |
| 聚集 | ℱ® | 聚集函数 | SELECT COUNT(*), AVG(A) FROM R |
| 分组 | γ_A,F® | GROUP BY | SELECT A, F FROM R GROUP BY A |
| 重命名 | ρ_S® | AS | SELECT * FROM R AS S |
6.2 SQL查询转换为关系代数
示例1:简单选择投影
sql
SELECT Sno, Name
FROM Student
WHERE Age > 20;
转换为关系代数:
π_Sno,Name(σ_Age>20(Student))
示例2:多表连接
sql
SELECT Student.Sno, Name, Cno, Grade
FROM Student, SC
WHERE Student.Sno = SC.Sno AND Grade > 80;
转换为关系代数:
π_Sno,Name,Cno,Grade(σ_Grade>80(Student ⋈ SC))
示例3:带聚集的分组查询
sql
SELECT Sno, AVG(Grade) as AvgGrade
FROM SC
GROUP BY Sno
HAVING AVG(Grade) > 85;
转换为关系代数:
σ_AvgGrade>85(γ_Sno,AVG(Grade)→AvgGrade(SC))
6.3 关系代数查询转换为SQL
示例1:选择+投影+连接
关系代数:
π_Name(σ_Grade>90(Student ⋈ SC))
转换为SQL:
sql
SELECT DISTINCT Name
FROM Student NATURAL JOIN SC
WHERE Grade > 90;
示例2:除法运算
关系代数:
SC ÷ Course
(查询选修了所有课程的学生)
转换为SQL:
sql
-- 方法1:双重NOT EXISTS
SELECT DISTINCT Sno
FROM SC AS SC1
WHERE NOT EXISTS (
SELECT * FROM Course
WHERE NOT EXISTS (
SELECT * FROM SC AS SC2
WHERE SC2.Sno = SC1.Sno AND SC2.Cno = Course.Cno
)
);
-- 方法2:COUNT比较
SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(DISTINCT Cno) = (SELECT COUNT(*) FROM Course);
示例3:差运算
关系代数:
Student - π_Sno,Name,Age(Student ⋈ SC)
(查询没有选课的学生)
转换为SQL:
sql
SELECT * FROM Student
WHERE Sno NOT IN (SELECT DISTINCT Sno FROM SC);
-- 或使用EXCEPT
SELECT * FROM Student
EXCEPT
SELECT Student.* FROM Student, SC WHERE Student.Sno = SC.Sno;
第七章 综合练习与案例
通过实际案例巩固关系代数的应用。
7.1 基础练习
使用以下关系进行练习:
Student(Sno, Sname, Age, Sex, Dept) -- 学生表
Course(Cno, Cname, Credit, Teacher) -- 课程表
SC(Sno, Cno, Grade) -- 选课表
练习1:单表查询
Q1:查询计算机系年龄大于20岁的女生
σ_Dept='计算机' ∧ Age>20 ∧ Sex='女'(Student)
Q2:查询所有学生的姓名和年龄
π_Sname,Age(Student)
Q3:查询所有课程的课程名
π_Cname(Course)
练习2:两表连接
Q4:查询选修了课程的学生姓名和成绩
π_Sname,Grade(Student ⋈ SC)
Q5:查询成绩大于90分的学生姓名和课程名
π_Sname,Cname(σ_Grade>90(Student ⋈ SC ⋈ Course))
7.2 综合案例
案例1:多表复杂查询
需求:查询选修了"数据库"课程且成绩高于张三的所有学生姓名
分步求解:
Step 1:找出"数据库"课程号
π_Cno(σ_Cname='数据库'(Course)) → 假设结果为{C1}
Step 2:找出张三的数据库成绩
π_Grade(σ_Sname='张三'(Student) ⋈ σ_Cno='C1'(SC)) → 假设结果为{85}
Step 3:找出数据库成绩高于85的学生
π_Sname(σ_Grade>85(σ_Cno='C1'(SC) ⋈ Student))
完整表达式:
π_Sname(σ_Grade>(π_Grade(σ_Sname='张三'(Student) ⋈ σ_Cname='数据库'(Course) ⋈ SC))
(Student ⋈ σ_Cname='数据库'(Course) ⋈ SC))
案例2:集合运算
需求:查询选修了C1或C2课程的学生学号
π_Sno(σ_Cno='C1'(SC)) ∪ π_Sno(σ_Cno='C2'(SC))
需求:查询同时选修了C1和C2课程的学生学号
π_Sno(σ_Cno='C1'(SC)) ∩ π_Sno(σ_Cno='C2'(SC))
需求:查询选修了C1但没选C2的学生学号
π_Sno(σ_Cno='C1'(SC)) - π_Sno(σ_Cno='C2'(SC))
7.3 典型问题
问题1:"全部"类型查询(除法运算)
需求:查询选修了所有课程的学生学号
解题关键:使用除法运算
SC ÷ π_Cno(Course)
验证:如果学生S1选了C1、C2、C3,S2只选了C1、C2
而所有课程是C1、C2、C3
则结果只有S1
需求:查询被所有学生都选修的课程
先投影出学生-课程关系的转置视图:
SC' = π_Cno,Sno(SC)
SC' ÷ π_Sno(Student)
问题2:嵌套查询转换
SQL嵌套查询:
sql
SELECT Sname FROM Student
WHERE Sno IN (
SELECT Sno FROM SC WHERE Grade > 90
);
转换为关系代数:
π_Sname(Student ⋈ π_Sno(σ_Grade>90(SC)))
或使用半连接:
π_Sname(Student ⋉ σ_Grade>90(SC))
第八章 面试与考试重点
8.1 高频考点
考点1:五种基本运算
必须记住的五种基本运算:
| 运算 | 符号 | 记忆要点 |
|---|---|---|
| 并 | ∪ | 合并两个兼容关系 |
| 差 | - | 从R中减去S |
| 笛卡尔积 | × | 所有组合 |
| 选择 | σ | 选行(水平切分) |
| 投影 | π | 选列(垂直切分) |
为什么这五个是基本的?
- 交运算可表示为:R ∩ S = R - (R - S)
- 连接运算可表示为:R ⋈ S = σ_条件(R × S)
- 除法运算可表示为:R ÷ S = π_X® - π_X((π_X® × S) - R)
考点2:关系代数表达式书写
常见题型:
- 给定需求,写出关系代数表达式
- 给定SQL,转换为关系代数
- 给定表达式,解释其含义
书写技巧:
1. 确定输出属性 → 投影
2. 确定过滤条件 → 选择
3. 确定需要哪些表 → 连接
4. 处理"全部"类型 → 除法
考点3:选择与投影的区别
| 比较项 | 选择(σ) | 投影(π) |
|---|---|---|
| 作用 | 选择行 | 选择列 |
| 切分方向 | 水平 | 垂直 |
| 结果元组数 | ≤原关系 | ≤原关系(去重) |
| 结果属性数 | =原关系 | ≤原关系 |
| 去重 | 不去重 | 自动去重 |
8.2 常见面试题
Q1:解释自然连接与等值连接的区别
答案要点:
1. 等值连接:
- 需要显式指定连接条件(A=B)
- 结果中保留两个连接属性列
- R ⋈_{R.B=S.B} S
2. 自然连接:
- 自动在同名属性上进行等值连接
- 结果中同名属性只保留一列
- R ⋈ S
3. 关系:
自然连接 = 等值连接 + 投影去除重复列
Q2:除法运算的应用场景
答案要点:
适用场景:包含"所有"、"全部"、"每一个"等关键词的查询
典型例子:
- 查询选修了所有课程的学生
- 查询被所有顾客购买过的商品
- 查询访问了所有页面的用户
公式:R ÷ S
- R必须包含S的所有属性
- 结果是R中与S完全匹配的元组在非公共属性上的投影
Q3:关系代数与SQL的对应关系
答案要点:
| 关系代数 | SQL组成部分 |
|----------|------------|
| π(投影)| SELECT子句 |
| σ(选择)| WHERE子句 |
| ⋈(连接)| JOIN子句 |
| ∪(并) | UNION |
| γ(分组)| GROUP BY |
| ℱ(聚集)| COUNT/SUM/AVG等 |
8.3 真题解析
软考真题1
题目: 设有关系R(A,B,C)和S(C,D),写出下列查询的关系代数表达式:
查询R和S在属性C上做自然连接后,B>5的元组的A值。
答案:
π_A(σ_B>5(R ⋈ S))
解析:
R ⋈ S:自然连接(在C上)σ_B>5(...):选择B>5的元组π_A(...):投影出A属性
软考真题2
题目: 关系R和S如下图所示,计算R ÷ S的结果。
R: S:
┌───┬───┐ ┌───┐
│ A │ B │ │ B │
├───┼───┤ ├───┤
│ 1 │ a │ │ a │
│ 1 │ b │ │ b │
│ 1 │ c │ │ c │
│ 2 │ a │ └───┘
│ 2 │ b │
│ 3 │ a │
└───┴───┘
答案:
结果:
┌───┐
│ A │
├───┤
│ 1 │
└───┘
解析:
- A=1对应的B值:{a,b,c} ⊇ S中的{a,b,c} ✓
- A=2对应的B值:{a,b} ⊉ S中的{a,b,c} ✗
- A=3对应的B值:{a} ⊉ S中的{a,b,c} ✗
所以只有A=1满足条件
附录
附录A:关系代数符号速查表
| 运算 | 符号 | 读法 | 运算类型 | LaTeX |
|---|---|---|---|---|
| 并 | ∪ | Union | 集合运算 | \cup |
| 交 | ∩ | Intersection | 集合运算 | \cap |
| 差 | - | Difference | 集合运算 | - |
| 笛卡尔积 | × | Cross Product | 集合运算 | \times |
| 选择 | σ | Sigma (Select) | 专门运算 | \sigma |
| 投影 | π | Pi (Project) | 专门运算 | \pi |
| 连接 | ⋈ | Bowtie (Join) | 专门运算 | \bowtie |
| 除 | ÷ | Division | 专门运算 | \div |
| 左外连接 | ⟕ | Left Outer Join | 扩展运算 | \leftouterjoin |
| 右外连接 | ⟖ | Right Outer Join | 扩展运算 | \rightouterjoin |
| 全外连接 | ⟗ | Full Outer Join | 扩展运算 | \fullouterjoin |
| 半连接 | ⋉ | Semi Join | 扩展运算 | \ltimes |
| 反连接 | ▷ | Anti Join | 扩展运算 | \rhd |
| 聚集 | ℱ 或 G | Aggregation | 扩展运算 | \mathcal{F} |
| 分组 | γ | Gamma (Group) | 扩展运算 | \gamma |
| 重命名 | ρ | Rho (Rename) | 扩展运算 | \rho |
附录B:五种基本运算详解
┌─────────────────────────────────────────────────────────────────┐
│ 五种基本运算 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 1. 并(∪) │
│ R ∪ S = { t | t ∈ R ∨ t ∈ S } │
│ 合并两个关系,去重 │
│ │
│ 2. 差(-) │
│ R - S = { t | t ∈ R ∧ t ∉ S } │
│ R中有但S中没有的 │
│ │
│ 3. 笛卡尔积(×) │
│ R × S = { t₁t₂ | t₁ ∈ R ∧ t₂ ∈ S } │
│ 所有可能的组合 │
│ │
│ 4. 选择(σ) │
│ σ_F(R) = { t | t ∈ R ∧ F(t) = true } │
│ 按条件选择行 │
│ │
│ 5. 投影(π) │
│ π_A(R) = { t[A] | t ∈ R } │
│ 选择列并去重 │
│ │
│ 其他运算都可以用这五种表示: │
│ • R ∩ S = R - (R - S) │
│ • R ⋈ S = π_去重(σ_条件(R × S)) │
│ • R ÷ S = π_X(R) - π_X((π_X(R) × S) - R) │
│ │
└─────────────────────────────────────────────────────────────────┘
附录C:参考资料
经典教材:
- 《数据库系统概念》(Database System Concepts)- Silberschatz等
- 《数据库系统原理》- 王珊、萨师煊
- 《数据库原理及应用》- 严蔚敏
在线资源:
- Stanford Database Course: https://cs145.stanford.edu/
- W3Schools SQL Tutorial: https://www.w3schools.com/sql/
- DB-Engines Rankings: https://db-engines.com/
工具推荐:
- RelaX - Relational Algebra Calculator: https://dbis-uibk.github.io/relax/
- SQL Fiddle: http://sqlfiddle.com/
本文档详细介绍了关系代数的基本运算,包括并、交、差、笛卡尔积(传统集合运算)和选择、投影、连接、除法(专门关系运算),以及扩展运算、运算符优先级、SQL对照、综合练习和面试重点。适合作为数据库原理学习和面试复习的参考资料。