数据库关系代数(Mysql)

下面用最经典的学生-课程数据库,把关系代数所有常用运算一次性讲全,
每条都配:含义 + 语法 + MySQL 对照 SQL + 例子结果说明。


0. 示例表结构(全程用这 3 张表)

1)学生表 Student

S(Sno, Sname, Sage, Ssex, Sdept)

  • Sno:学号
  • Sname:姓名
  • Sage:年龄
  • Ssex:性别
  • Sdept:所在系

2)课程表 Course

C(Cno, Cname, Credit, Tno)

  • Cno:课号
  • Cname:课程名
  • Credit:学分
  • Tno:教师号

3)选课表 SC

SC(Sno, Cno, Grade)

  • Sno:学号
  • Cno:课号
  • Grade:成绩

1. 传统集合运算

1.1 并(Union)∪

含义:两个同结构关系的所有元组,去重合并。

关系代数:

R ∪ S

MySQL:

SELECT * FROM R
UNION
SELECT * FROM S;

例子:
查询计算机系 或 数学系的所有学生。

σ[Sdept='CS'(S)] ∪ σ[Sdept='MA'(S)]

1.2 交(Intersection)∩

含义:同时出现在 R 和 S 中的元组。

关系代数:

R ∩ S

MySQL:

SELECT * FROM R
INTERSECT
SELECT * FROM S;

例子:
查询既选了 1 号课,又选了 2 号课的学生学号。

π[Sno(σ[Cno=1(SC])] ∩ π[Sno(σ[Cno=2(SC])]

1.3 差(Difference)−

含义:在 R 中但不在 S 中的元组。

关系代数:

R − S

MySQL:

SELECT * FROM R
EXCEPT
SELECT * FROM S;

例子:
查询选了课但没选 1 号课的学生。

π[Sno(SC)] − π[Sno(σ[Cno=1(SC])]

2. 专门关系运算(核心)

2.1 选择 σ(Selection)

行过滤:满足条件的元组。

语法:

σ[条件](关系)

例子 1:查询计算机系学生

σ[Sdept='CS'(S)]

SQL:

SELECT * FROM Student WHERE Sdept = 'CS';

例子 2:成绩 ≥ 90

σ[Grade>=90(SC)]

2.2 投影 π(Projection)

列过滤:保留某些属性,去掉重复行。

语法:

π[属性列表](关系)

例子:查询所有学生的姓名和所在系

π[Sname,Sdept(S)]

SQL:

SELECT DISTINCT Sname, Sdept FROM Student;

2.3 笛卡尔积 ×(Cartesian Product)

所有元组两两组合,不加条件。

语法:

R × S

SQL:

SELECT * FROM R, S;
-- 或
SELECT * FROM R CROSS JOIN S;

例子:学生 × 课程

S × C

2.4 自然连接 ⋈(Natural Join)

自动按同名属性等值连接,去重公共列。

语法:

R ⋈ S

SQL:

SELECT * FROM R NATURAL JOIN S;

经典例子:查询学生及其选课成绩

S ⋈ SC

2.5 条件连接(θ-连接)⋈[条件]

笛卡尔积 + 选择,等价于内连接。

语法:

R ⋈[条件] S

等价:

σ[条件](R × S)

SQL:

SELECT * FROM R JOIN S ON 条件;

例子:学生与选课按学号连接

S ⋈[S.Sno=SC.Sno] SC

2.6 左外连接 / 右外连接 / 全外连接

左外连接 ⋊=(Left Outer Join)

左边全部保留,右边匹配不上填 NULL。

关系代数:

S ⋊= SC

SQL:

SELECT * FROM S LEFT JOIN SC ON S.Sno=SC.Sno;

用途:查所有学生,包括没选课的


3. 高级运算(考试/工程高频)

3.1 除运算 ÷(Division)

“包含全部”类查询:包含 S 中所有相关元组的 R 元组。

语法:

R ÷ S

经典例子:
查询选了所有课程的学生学号。

π[Sno,Cno(SC)] ÷ π[Cno(C)]

SQL 思路(分组+计数):

SELECT Sno
FROM SC
GROUP BY Sno
HAVING COUNT(DISTINCT Cno) = (SELECT COUNT(*) FROM C);

3.2 更名运算 ρ(Rename)

修改关系名/属性名,解决重名冲突。

语法:

ρ[新关系名(新属性1,新属性2...)(R)]

例子:把 SC 改名为 SC_NEW(S#, C#, G)

ρ[SC_NEW(S#,C#,G)(SC)]

SQL:

SELECT Sno AS S#, Cno AS C#, Grade AS G FROM SC AS SC_NEW;

4. 组合查询大全(考试必背)

例 1:查询选了“数据库”的学生姓名

π[Sname( σ[Cname='数据库'(C ⋈ SC ⋈ S) ]]

SQL:

SELECT DISTINCT Sname
FROM Student
JOIN SC ON Student.Sno=SC.Sno
JOIN Course ON SC.Cno=Course.Cno
WHERE Cname='数据库';

例 2:查询没选 1 号课的学生

π[Sno(S)] − π[Sno( σ[Cno=1(SC]) ]

例 3:查询至少选了 2 门课的学生

π[Sno( σ[COUNT(*)>=2( γ[Sno;COUNT(*)(SC]) ]]

(带分组扩展 γ)

SQL:

SELECT Sno FROM SC GROUP BY Sno HAVING COUNT(*)>=2;

例 4:查询成绩为空的学生(没成绩)

π[Sname(S ⋊= σ[Grade IS NULL(SC]) ]

例 5:查询年龄大于 20 岁的女生

σ[Sage>20 ∧ Ssex='女'(S)]

5. 关系代数 ↔ SQL 速记表

关系代数SQL 对应作用
σ条件WHERE 条件选行
πA,BSELECT A,B选列
R × SCROSS JOIN笛卡尔积
R ⋈ SNATURAL JOIN自然连接
R ⋈[c] SJOIN ON c条件连接
R ⋊= SLEFT JOIN左外连接
R ∪ SUNION
R ∩ SINTERSECT
R − SEXCEPT
R ÷ SGROUP BY+HAVING包含全部
ρAS更名