软考笔记(7)--数据库关系代数
一、关系代数
关系代数是一种过程化查询语言,它包括一个运算的集合,这些运算以一个或两个关系为输入,产生一个新的关系作为结果。
关系代数的基本运算有:选择、投影、集合并、集合差和笛卡尔积,在基本运算之外还有一个其他运算,即集合交、自然连接和赋值。
选择、投影都是一元运算,因为他们都是对一个关系进行运算;另外三个运算对两个关系进行运算,所以称为二元运算。
1.1、选择(select)
选择运算选出满足给定谓词的元组,用小写希腊字母(σ)来表示,而将谓词写作σ的下标。参数关系在σ后的括号中。 选择相当于数据库关键字where的作用。
通常还允许在选择谓词中进行比较,使用=,≠,<,≤,>和≥,另外还可以用连词and(Λ)、or(ν)和not(¬)将多个谓词合并称一个较大的谓词。
选择谓词中还可以包含两个属性的比较
定义关系employee如下:
id | name | dept_name | subject | salary |
1001 | Jack | Music | Music | 7500 |
1002 | Bob | History | War History | 8000 |
1003 | Alice | Physics | Physics | 8500 |
1004 | Mary | History | War History | 9000 |
1005 | James | Music | Music | 9000 |
定义关系teacher如下:
id | name | age | sex |
1001 | Jack | 35 | man |
1002 | Green | 21 | man |
1003 | Alice | 28 | woman |
例1:选择部门为History的所有元组
σdept_name = 'History' (employee)
例2:选择薪资大于8000的所有元组
σsalary > 8000 (employee)
例3:选择历史系薪资大于8000的元组
σdept_name = 'History' Λ salary > 8000 (employee)
例4:选择部门和科室名称一样的所有元组
σdept_name = subject (employee)
1.2、投影(Projection)
投影运算也是一元运算,它返回作为参数的关系,但把某些属性排除在外。由于关系是一个集合,所以所有的重复行均被去除。投影相当于数据库关键字select的作用,用大写希腊字母(π)表示,列举所有需要的在结果中出现的属性作为π的下标,作为参数的关系在π的后面的括号中。
例1:查询employee关系中所有的id、name和dept_name
πid,name,dept_name(employee)
1.3、关系运算组合
关系运算的结果自身也是一个关系,实际场景中的查询更多的是复杂的查询。需要查询所有历史系的员工的姓名,则表达式如下:
πname(σdept_name = 'History' (employee))
将多个关系代数运算组合成一个关系代数表达式。
1.4、集合并运算
并运算相当于将两个集合进行合并,并运算用符号(∪)表示,如将关系R和关系S进行并运算记作 R ∪ S,要使得并运算需要满足两个条件
1、关系R和关系S必须是同元的,即属性必须相同(两个集合字段相同)
2、对所有的i,R的第i个属性的域必须和S的第i个属性的域相同(相同字段的取值范围也相同)
例1:查询音乐系和历史系薪资大于8500的员工姓名
查询音乐系薪资大于8500的员工: πname(σdept_name = 'Music' Λ salary > 8500 (employee))
查询历史系薪资大于8500的员工: πname(σdept_name = 'History' Λ salary > 8500 (employee))
则将两个结果进行合并的表达式为: πname(σdept_name = 'Music' Λ salary > 8500 (employee)) ∪ πname(σdept_name = 'History' Λ salary > 8500 (employee))
1.5、集合差运算
差运算用字符(—)表示,用于找到在一个关系中而不在另一个关系中的元组。表达式 R — S 表示结果在R中而不在S中的元组。
例1:查询音乐系中的不是男老师的员工姓名
查询音乐系员工:πname(σdept_name = 'Music' (employee))
查询男老师姓名:πname(σsex = 'man' (teacher))
则将两个结果用差运算表达式为:πname(σdept_name = 'Music' (employee))— πname(σsex = 'man' (teacher))
1.6、笛卡尔积
笛卡尔积用字符(X)表示,使得可以将任意两个关系的信息集合在一起。将关系r1和r2的笛卡尔积写作r1 X r2
由于相同的属性可能同时出现在r1和r2中,所以需要提出一个命名机制来区别这些属性,通常将关系名称附加到该属性上, 属性只在一个关系中存在的可以省略掉关系名称前缀。例如 r = employee X teacher 的关系模式所有属性如下:
(employe.id, employe.name, dept_name, subject, salary, teacher.id, teacher.name, age, sex)
r = emplpyee X teacher的所有元组结果如下:
employe.id | employe.name | dept_name | subject | salary | teacher.id | teacher.name | age | sex |
1001 | Jack | Music | Music | 7500 | 1001 | Jack | 35 | Man |
1001 | Jack | Music | Music | 7500 | 1002 | Green | 21 | Man |
1001 | Jack | Music | Music | 7500 | 1003 | Alice | 28 | Woman |
1002 | Bob | History | War History | 8000 | 1001 | Jack | 35 | Man |
1002 | Bob | History | War History | 8000 | 1002 | Green | 21 | Man |
1002 | Bob | History | War History | 8000 | 1003 | Alice | 28 | Woman |
1003 | Alice | Physics | Physics | 8500 | 1001 | Jack | 35 | Man |
1003 | Alice | Physics | Physics | 8500 | 1002 | Green | 21 | Man |
1003 | Alice | Physics | Physics | 8500 | 1003 | Alice | 28 | Woman |
1004 | Mary | History | War History | 9000 | 1001 | Jack | 35 | Man |
1004 | Mary | History | War History | 9000 | 1002 | Green | 21 | Man |
1004 | Mary | History | War History | 9000 | 1003 | Alice | 28 | Woman |
1005 | James | Music | Music | 9000 | 1001 | Jack | 35 | Man |
1005 | James | Music | Music | 9000 | 1002 | Green | 21 | Man |
1005 | James | Music | Music | 9000 | 1003 | Alice | 28 | Woman |
例1:查询历史系中的所有老师薪资
πsalary(σemploey.name = teacher.name (σdept_name = 'History'(employee X teacher)))
1.7、集合交运算
集合交运算用符号(∩)表示,集合交运算表示两个集合交集,可以用集合差来表示,如 R ∩ S = R - ( R - S)
例1:查询历史系中的男老师姓名
πname(σdept_name= 'History' (employee)) ∩ πname(σsex= 'Man' (teacher))
1.8、自然连接运算
自然连接是对笛卡尔积点查询进行简化的表达方式。自然连接用符号(⋈)表示,自然连接运算首先形成两个参数的笛卡尔积,然后基于两个关系模式中都出现的属性上的相等性进行选择,最后还会去除掉重复属性。比如employe和teacher进行自然连接运算。
根据id和name来进行自然连接,表达式为:πid, name(employe ⋈ teacher),形成的集合为:
id | name | dept_name | subject | salary | age | sex |
1001 | Jack | Music | Music | 7500 | 35 | Man |
1003 | Alice | Physics | Physics | 8500 | 28 | Woman |
1.9、赋值运算
赋值运算相当于定义变量,将某些表达式用一个临时变量赋值的方式代替。赋值运算通过符号(←)表示
如定义:temp ← employe ⋈ teacher, 则 πid, name(temp) 就相当于是 πid, name(employe ⋈ teacher)
1.10、外连接运算
外连接运算是连接运算的扩展,可以处理缺失的信息,外连接在连接结果中添加额外的元组。外连接分为左外连接(⋊)、右外连接(⋉)和全外连接(⋊⋉)
左外连接:取出左侧关系中所有与右侧关系的人一元组都不匹配的元组,用空值填充所有来自右侧关系的属性,再把产生的元组加到自然连接的结果中。
右外连接:与左外连接对称,用空值填充来自右侧关系的所有与左侧关系的任一元组都不匹配的元组,将结果加到自然连接的结果中。
全外连接:既做左外连接又做右外连接,既填充左侧关系中与右侧关系的任一元组都不匹配的元组,又填充右侧关系中与左侧关系的任一元组都不匹配的元组,并把结果添加到自然连接到结果中。
1.11、广义投影
广义投影允许在投影列表中使用算术运算和字符串函数来对投影进行扩展。如employee中查询员工每个月的薪资,表达式为:πname,salary/12(employee)
1.12、聚集运算
聚集运算用符号(g)表示,聚集运算时可以用来对值的集合使用聚集函数,例如计算最小值或平均值等。
聚集函数输入值的一个汇集,将单一值作为结果返回,例如聚集函数sum输入值的一个汇集,返回这些值的和,将函数sum用于汇集{1, 2, 3, ,4 ,5} 上返回的值为15
例1:统计所有员工的薪资总和,表达式为:gsum(salary)(employee)
通常SQL语句都可以用关系代数来重写,比如:
select A1, A2, sum(A3) from r1, r2, r3 where P group by A1, A2
等价于关系代数表达式: A1, A2, gsum(A3)(πA1,A2,A3(σP (r1 X r2 X r3)))
二、元组关系演算
元组关系演算上非过程化的查询语言,它只描述所需信息,而不给出获得该信息的具体过程。
元组关系运算的查询表达式为:{ t | P (t) }
也就是说,它是所有使谓词P为真大元组t的集合,我们用 t[A] 表示元组t在属性A上的值, 并用 t ∈ r 表示元组t在关系r中。
例1:查询所有薪资在8000以上的员工id、name、dept_name、subject和salary
{ t | t ∈ employee Λ t [salary] > 8000}
假如我们只需要获取员工的id,而不需要employee的其他字段。为了用元组关系演算来书写这个查询,需要为模式(id)上的关系写一个表达式。此时需要引入数理逻辑中的“存在”结构,表达式为:
∃t ∈ r(Q(t)),表示“关系r中存在元组t使谓词Q(t)为真”
例2:查询所有薪资大于8000的员工id
{ t | ∃s ∈ employee( t [id] = s [id] Λ s [salary] > 8000 ) }
含义为:在关系employee中存在元组s 使 t 和 s 在属性ID上的值相等,且 s 在属性salary上的值大于8000