第6章 形式化关系查询语言
总结
- 关系代数(relational algebra)定义了一套在表上运算且输出结果也是表的的代数运算。这些运算可以混合使用来得到表达所希望查询的表达式。关系代数定义了关系查询语言中使用的基本运算。
- 关系代数运算可以分为:
- 基本运算。
- 附加的运算,可以用基本运算表达式。
- 扩展的运算,其中的一些扩展了关系代数的表达能力。
- 关系代数是一种简洁的、形式化的语言,不适合那些偶尔使用数据库系统的用户。因此,商用数据库系统采用更多“语法修饰”的语言。(SQL是基于关系代数的)
- 元组关系演算(tuple relational calculus)和域关系演算(domain relational calculus)是非过程化语言,代表了关系查询语言所需的基本 能力。基本关系代数是一种过程化语言,在能力上等价于被限制在安全表达式范围内的关系演算的这两种形式。
- 关系演算是简洁的、形式化的语言,并不适合那些偶尔使用数据库系统的用户。这两种形式化语言构成了两种更易使用的语言QBE和Datalog的基础。
术语
- 关系代数
- 关系代数运算
- 选择(Select) σ
σdept_name =“Physics” (instructor )
σsalary>90000 (instructor)
σdept_name =“Physics”∧salary>90000 (instructor )
σdept_name =building (department)
-
- 投影(Project) ∏
∏ID, name, salary (instructor )
∏name (σdept_name =“Physics” (instructor))
∏course_id (σsemester =“Fall”∧year=2009 (section))
∏course_id (σsemester =“Spring”∧year=2010 (section))
-
- 并(Union) ∪
∏course_id (σsemester =“Fall”∧year=2009 (section)) ∪ ∏course_id (σsemester =“Spring” ∧year=2010 (section))
-
- 集合差(Set-Difference) −
∏course_id (σsemester =“Fall”∧year=2009 (section)) -
∏course_id (σsemester =“Spring” ∧year=2010 (section))
-
- 笛卡尔积(Cartesian-product) ×
r = instructor × teaches的关系模式为:
(instructor.ID, instructor.name, instructor.dept name, instructor.salary,
teaches.ID, teaches.course id, teaches.sec id, teaches.semester, teaches.year)
对于只在两个关系之一中出现的属性,通常省略其关系名前缀:
(instructor.ID, name, dept name, salary, teaches.ID, course id, sec id, semester, year)
σdept_name =“Physics”(instructor × teaches)
σinstructor.ID =teaches.ID (σdept_name =“Physics”(instructor × teaches))
∏name, course_id (σinstructor.ID =teaches.ID (σdept_name =“Physics”(instructor × teaches)))
∏name, course_id (σinstructor.ID =teaches.ID ((σdept_name =“Physics”(instructor)) × teaches))
-
- 更名(rename) ρ
ρx (E)
ρx (A1,A2,...,An) (E)
计算最高工资:
step1:
∏instructor.salary (σinstructor.salary < d.salary (instructor × ρd (instructor)))
step2:
∏salary(instructor) - ∏instructor.salary (σinstructor.salary < d.salary (instructor × ρd (instructor)))
- 附加的运算
- 集合交(set intersection) ∩
∏course_id (σsemester =“Fall”∧year=2009 (section)) ∩
∏course_id (σsemester =“Spring”∧year=2010 (section))
r ∩ s = r − (r − s)
- 自然连接(natural join) ⋈
∏name, course_id (instructor ⋈ teaches)
自然连接的形式化定义:r ⋈ s = ∏R ∪ S (σr.A1 =s.A1 ∧r.A2 =s.A2 ∧...∧r.An =s.An (r × s))
R ∩ S = {A1, A2, . . . , An}。
如果r(R)和s(S)不含有任何相同属性,即R∩S = Ø,那么r ⋈ s = r × s
找出计算机系中所有教师及他们教授课程名称:
∏name,title (σdept name =“Comp. Sci.” (instructor ⋈ teaches ⋈ course))
(instructor ⋈ teaches) ⋈ course 等价于 instructor ⋈ (teaches ⋈ course) 也就是说自然连接是可结合的(associative)
theta join连接:θ是模式R∪S的属性上的谓词,则r⋈θs定义如下:
r ⋈θ s = σθ(r × s)
- 赋值运算(assignment operation) ←
有时通过给临时关系变量赋值的方法来写关系代数表达式会非常方便。我们可以把 r ⋈ s 写作:
temp1 ← R × S
temp2 ← σr.A1 =s.A1 ∧r.A2 =s.A2 ∧...∧r.An =s.An (temp1)
result = ∏R ∪ S (temp2)
注意:赋值必须是赋给一个临时关系变量。对永久关系的赋值形成了对数据库的更改。赋值运算不能增强关系代数的表达能力,但是可以使复杂查询的表达变得简单。
- 外连接(Outer join)
-
-
- 左外连接(left outer join) ⟕
-
外连接运算可以用基本关系代数运算表示。例如, r ⟕ s 可以写成:
(r ⋈ s) ∪ (r − ∏R(r ⋈ s)) × {(null,...,null)}
其中常数关系 {(null,...,null)} 的模式是S − R
-
-
- 右外连接(right outer join) ⟖
- 全外连接(full outer join) ⟗
-
- 多重集
Gsum(salary)(instructor)
Gcount−distinct(ID)(σsemester=“Spring”∧year =2010(teaches))
dept_nameGaverage(salary)(instructor)
Gaverage(salary)(instructor)
聚合操作G的一般形式如下:G1,G2,...,GnGF1(A1), F2(A2),..., Fm(Am)(E)
其中E是任何关系代数表达式;G1,G2,列出一份要分组的属性;每个Fi是一个聚合函数;每个Ai都是属性名。操作的意义如下:表达式E的结果按如下方式分组:
1.同一组中所有元组在G1,G2,...,Gn上的值相同。
2.不同组中元组在G1,G2,...,Gn上的值不同。
因此,各组可以用属性G1,G2,...,Gn上的值来唯一标识。对于每个组(g1,g2,...,gn)来说,结果中有一个元组(g1,g2,...,gn,a1,a2,...,am),其中对每个i,ai是将聚集函数Fi作用于该组的属性Ai上的多重值集所得到的结果。
作为聚集运算的特例,属性列G1,G2,...,Gn可以是空的,在这种情况下,会有唯一一组包含关系中所有的元组。这相当于没有分组。
- 分组
- 空值
- sql与关系代数
select A1, A2, . . . , An
from r1, r2, . . . , rm
where P
is equivalent to:
∏A1, A2,...,An (σP (r1 × r2 × · · · × rm))
select A1, A2, sum(A3)
from r1, r2, . . . , rm
where P
group by A1, A2
is equivalent to:
A1, A2Gsum(A3)(∏A1, A2,..., An (σP (r1 × r2 × · · · × rm)))
- 元组关系演算
元组关系演算中的查询表达式:
{t | P(t)}
它是所有使谓词 P 为真的元组 t 的集合。t[ A ]表示元组 t 在属性 A 上的值,并用 t ∈ r 表示元组t在关系 r 中。
工资在80000美元以上教师的ID、name、dept_name和salary:
{t | t ∈ instructor ∧ t[salary] > 80000}
关系 r 中存在元组 t 使谓词 Q(t) 为真:
∃ t ∈ r (Q(t))
用这种记法,我们可以将查询“工资大于80000美元的所有教师的ID”的表述为:
{t | ∃ s ∈ instructor( t[ ID ] = s[ ID ] ∧ s[ salary ] > 80000 ) }
它是满足如下条件的元组 t 的集合:在关系 instructor 中存在元组 s 使 t 和 s 在属性 ID 上的值相等,且 s 在属性 salary 上的值大于80 000美元。
元组变量 t 只定义在 ID 属性上,因为这一属性是对 t 进行限制的条件所涉及的唯一属性。因此,结果得到(ID)上的关系。
找出位置在Watson楼的系中的所有教师姓名:
{t | ∃ s ∈ instructor (t[name] = s[name]
∧ ∃ u ∈ department (u[dept_name] = s[dept_name]
∧ u[building] = “Watson”))}
2009年秋季或者2010年春季或者这两个学期都开设的所有课程的集合:
{t | ∃ s ∈ section (t[course_id ] = s[course_id ])
∧ s[semester] = “Fall” ∧ s[year] = 2009)
∨ ∃ u ∈ section (u[course_id ] = t[course_id ])
∧ u[semester] = “Spring” ∧ u[year] = 2010)}
2009年秋季或者2010年春季或者这两个学期都开设的所有课程course_id:
{t | ∃ s ∈ section (t[course id ] = s[course id ])
∧ s[semester] = “Fall” ∧ s[year] = 2009)
∧ ∃ u ∈ section (u[course id ] = t[course id ])
∧ u[semester] = “Spring” ∧ u[year] = 2010)}
2009年秋季开设而在2010年春季不开设的所有课程:
{t | ∃ s ∈ section (t[course id ] = s[course id ])
∧ s[semester] = “Fall” ∧ s[year] = 2009)
∧ ¬ ∃ u ∈ section (u[course id ] = t[course id ])
∧ u[semester] = “Spring” ∧ u[year] = 2010)}
- 域关系演算
- 表达式安全性
- 语言的表达能力
以下三者都是等价的:
基本关系代数(没有扩展的关系代数操作)
仅限于安全表达式的元组关系演算
仅限于安全表达式的域关系演算
。
。
浙公网安备 33010602011771号