第六章 形式化关系查询语言
6.1关系代数
基本关系运算:
select: σ ,选择运算选出满足特定谓词的元组
例如 :
选出物理系的教职人员:
σ
d
e
p
t
_
n
a
m
e
=
′
P
h
y
s
i
c
s
′
(
i
n
s
t
r
u
c
t
o
r
)
\sigma_{dept\_name='Physics'}(instructor)
σ d e p t _ n a m e = ′ P h y s i c s ′ ( i n s t r u c t o r ) 选出物理系且工资大于80000的教职人员:
σ
d
e
p
t
_
n
a
m
e
=
′
P
h
y
s
i
c
s
′
∧
(
s
a
l
a
r
y
>
80000
)
(
i
n
s
t
r
u
c
t
o
r
)
\sigma_{dept\_name='Physics' \land (salary>80000)}(instructor)
σ d e p t _ n a m e = ′ P h y s i c s ′ ∧ ( s a l a r y > 8 0 0 0 0 ) ( i n s t r u c t o r )
project: Π , 返回筛选属性后的集合,只显示选择的属性
例如:
选出老师的ID和name
∏
i
d
,
n
a
m
e
(
i
n
s
t
r
u
c
t
o
r
)
\prod_{}{id,name}(instructor)
∏ i d , n a m e ( i n s t r u c t o r ) 选出物理系老师的ID name salary
∏
i
d
,
n
a
m
e
,
s
a
l
a
r
y
(
σ
d
e
p
t
_
n
a
m
e
=
′
P
h
y
s
i
c
s
′
(
i
n
s
t
r
u
c
t
o
r
)
)
\prod_{}{id,name,salary}(\sigma_{dept\_name='Physics'}(instructor))
∏ i d , n a m e , s a l a r y ( σ d e p t _ n a m e = ′ P h y s i c s ′ ( i n s t r u c t o r ) )
union: ∪ 集合的并集运算
例子:
找出开设在2009年秋季或2010年春季或二者都开的课程:
∏
c
o
u
r
s
e
_
i
d
(
σ
s
e
m
e
s
t
e
r
=
′
F
a
l
l
′
∧
y
e
a
r
=
2009
(
s
e
c
t
i
o
n
)
)
⋃
∏
c
o
u
r
s
e
_
i
d
(
σ
s
e
m
e
s
t
e
r
=
′
S
p
r
i
n
g
′
∧
y
e
a
r
=
2010
(
s
e
c
t
i
o
n
)
)
\prod_{}{course\_id}(\sigma_{semester='Fall'\land{}year=2009}(section))\bigcup_{ }\prod_{}{course\_id}(\sigma_{semester='Spring'\land{}year=2010}(section))
∏ c o u r s e _ i d ( σ s e m e s t e r = ′ F a l l ′ ∧ y e a r = 2 0 0 9 ( s e c t i o n ) ) ⋃ ∏ c o u r s e _ i d ( σ s e m e s t e r = ′ S p r i n g ′ ∧ y e a r = 2 0 1 0 ( s e c t i o n ) )
set difference: − 集合差运算,r-s 表示在r中但不在s中的元组
例子:
找出开设在2009年秋季但不在2010年春季开设的课程:
∏
c
o
u
r
s
e
_
i
d
(
σ
s
e
m
e
s
t
e
r
=
′
F
a
l
l
′
∧
y
e
a
r
=
2009
(
s
e
c
t
i
o
n
)
)
⋃
∏
c
o
u
r
s
e
_
i
d
(
σ
s
e
m
e
s
t
e
r
=
′
S
p
r
i
n
g
′
∧
y
e
a
r
=
2010
(
s
e
c
t
i
o
n
)
)
\prod_{}{course\_id}(\sigma_{semester='Fall'\land{}year=2009}(section))\bigcup_{ }\prod_{}{course\_id}(\sigma_{semester='Spring'\land{}year=2010}(section))
∏ c o u r s e _ i d ( σ s e m e s t e r = ′ F a l l ′ ∧ y e a r = 2 0 0 9 ( s e c t i o n ) ) ⋃ ∏ c o u r s e _ i d ( σ s e m e s t e r = ′ S p r i n g ′ ∧ y e a r = 2 0 1 0 ( s e c t i o n ) )
Cartesian product: x ,笛卡尔积运算
例子:
找出物理系的所有教师以及他们教授的课程
∏
n
a
m
e
,
c
o
u
r
s
e
_
i
d
(
σ
i
n
s
t
r
u
c
t
o
r
.
i
d
=
t
e
a
c
h
e
s
.
i
d
∧
d
e
p
t
n
a
m
e
=
′
P
h
y
s
i
c
s
′
(
i
n
s
t
r
u
c
t
o
r
×
t
e
a
c
h
e
s
)
)
\prod_{}{name,course\_id}(\sigma_{instructor.id=teaches.id }\land_{dept_name='Physics'}(instructor×teaches) )
∏ n a m e , c o u r s e _ i d ( σ i n s t r u c t o r . i d = t e a c h e s . i d ∧ d e p t n a m e = ′ P h y s i c s ′ ( i n s t r u c t o r × t e a c h e s ) )
rename: ρ ,用于更名
ρ
x
(
A
1
,
A
2
,
.
.
.
A
n
)
(
E
)
\rho_{x(A1,A2,...An)}(E)
ρ x ( A 1 , A 2 , . . . A n ) ( E ) 返回表达式E的结果并将名称改为x,并将属性名改为A1,A2,…An
附加的关系运算
交集运算 ∩
例如:
找出开设在2009年秋季以及2010年春季都开设的课程:
∏
c
o
u
r
s
e
_
i
d
(
σ
s
e
m
e
s
t
e
r
=
′
F
a
l
l
′
∧
y
e
a
r
=
2009
(
s
e
c
t
i
o
n
)
)
⋂
∏
c
o
u
r
s
e
_
i
d
(
σ
s
e
m
e
s
t
e
r
=
′
S
p
r
i
n
g
′
∧
y
e
a
r
=
2010
(
s
e
c
t
i
o
n
)
)
\prod_{}{course\_id}(\sigma_{semester='Fall'\land{}year=2009}(section))\bigcap_{ }\prod_{}{course\_id}(\sigma_{semester='Spring'\land{}year=2010}(section))
∏ c o u r s e _ i d ( σ s e m e s t e r = ′ F a l l ′ ∧ y e a r = 2 0 0 9 ( s e c t i o n ) ) ⋂ ∏ c o u r s e _ i d ( σ s e m e s t e r = ′ S p r i n g ′ ∧ y e a r = 2 0 1 0 ( s e c t i o n ) )
自然连接运算 ⋈
例如:
找出所有教师的姓名以及他们教授的课程id
∏
n
a
m
e
,
c
o
u
r
s
e
_
i
d
(
i
n
s
t
r
u
c
t
o
r
⋈
t
e
a
c
h
e
s
)
\prod_{}{name,course\_id}(instructor\Join_{}teaches)
∏ n a m e , c o u r s e _ i d ( i n s t r u c t o r ⋈ t e a c h e s ) 找出计算机系的老师姓名以及他们的课程名称
∏
n
a
m
e
,
t
i
t
l
e
(
σ
d
e
p
t
_
n
a
m
e
=
′
C
o
m
p
′
(
i
n
s
t
r
u
c
t
o
r
⋈
t
e
a
c
h
e
s
⋈
c
o
u
r
s
e
)
)
\prod_{}{name,title}({\sigma_{dept\_name='Comp'}}(instructor\Join_{}teaches\Join_{}course))
∏ n a m e , t i t l e ( σ d e p t _ n a m e = ′ C o m p ′ ( i n s t r u c t o r ⋈ t e a c h e s ⋈ c o u r s e ) )
一些扩展的运算操作:
可以在属性处进行基本运算:
∏
i
d
,
n
a
m
e
,
s
a
l
a
r
y
/
12
(
i
n
s
t
r
u
c
t
o
r
)
\prod_{}{id,name,salary/12}(instructor)
∏ i d , n a m e , s a l a r y / 1 2 ( i n s t r u c t o r ) 可以使用聚类函数:
G
s
u
m
(
s
a
l
a
r
y
)
(
i
n
s
t
r
u
c
t
o
r
)
G_{sum(salary)}(instructor)
G s u m ( s a l a r y ) ( i n s t r u c t o r )
6.2元组关系演算
通用格式:
{
t
∣
P
(
t
)
}
\{t|P(t)\}
{ t ∣ P ( t ) } 表示使所有P为真的t的元组集合
找出工资在80000美元以上的教师的ID、name、dept_name、salary:
{
t
∣
t
∈
i
n
s
t
r
u
c
t
o
r
∧
t
[
s
a
l
a
r
y
]
>
80000
}
\{t|t\in{instructor}\land t[salary]>80000\}
{ t ∣ t ∈ i n s t r u c t o r ∧ t [ s a l a r y ] > 8 0 0 0 0 } 找出工资大于80000美元的教师的ID
{
t
∣
∃
s
∈
i
n
s
t
r
u
c
t
o
r
(
t
[
I
D
]
=
s
[
I
D
]
∧
s
[
s
a
l
a
r
y
]
>
80000
)
}
\{t|\exists{s}\in{instructor}(t[ID]=s[ID]\land{s[salary]>80000)}\}
{ t ∣ ∃ s ∈ i n s t r u c t o r ( t [ I D ] = s [ I D ] ∧ s [ s a l a r y ] > 8 0 0 0 0 ) }
练习题:
考虑下图所示的关系数据库,主码加了下划线。给出关系代数表达式来表达下列的每一个查询:
a.找出First Bank Corporation的所有员工姓名
∏
p
e
r
s
o
n
_
n
a
m
e
(
σ
c
o
m
p
a
n
y
_
n
a
m
e
=
“
F
i
r
s
t
B
a
n
k
C
o
r
p
o
r
a
t
i
o
n
”
(
w
o
r
k
s
)
)
\prod_{}{person\_name} (\sigma_{company\_name = “First Bank Corporation” }(works))
∏ p e r s o n _ n a m e ( σ c o m p a n y _ n a m e = “ F i r s t B a n k C o r p o r a t i o n ” ( w o r k s ) ) b.找出First Bank Corporation所有员工的姓名和居住城市
∏
p
e
r
s
o
n
_
n
a
m
e
,
c
i
t
y
(
e
m
p
l
o
y
e
e
⋈
(
σ
c
o
m
p
a
n
y
_
n
a
m
e
=
“
F
i
r
s
t
B
a
n
k
C
o
r
p
o
r
a
t
i
o
n
”
(
w
o
r
k
s
)
)
)
\prod_{}{person\_name,city }{ }(employee \Join(\sigma_{company\_name = “First Bank Corporation”} (works)))
∏ p e r s o n _ n a m e , c i t y ( e m p l o y e e ⋈ ( σ c o m p a n y _ n a m e = “ F i r s t B a n k C o r p o r a t i o n ” ( w o r k s ) ) ) c.找出First Bank Corporation所有年收入在10000美元以上的员工姓名和居住的街道、城市。
∏
p
e
r
s
o
n
_
n
a
m
e
,
s
t
r
e
e
t
,
c
i
t
y
(
σ
(
c
o
m
p
a
n
y
_
n
a
m
e
=
“
F
i
r
s
t
B
a
n
k
C
o
r
p
o
r
a
t
i
o
n
”
∧
s
a
l
a
r
y
>
10000
)
w
o
r
k
s
⋈
e
m
p
l
o
y
e
e
)
\prod_{}person\_name, street, city(\sigma_{(company\_name = “First Bank Corporation” ∧ salar y > 10000)}works \Join employee)
∏ p e r s o n _ n a m e , s t r e e t , c i t y ( σ ( c o m p a n y _ n a m e = “ F i r s t B a n k C o r p o r a t i o n ” ∧ s a l a r y > 1 0 0 0 0 ) w o r k s ⋈ e m p l o y e e ) d.找出所有居住地与工作的公司在同一城市的员工姓名
∏
p
e
r
s
o
n
_
n
a
m
e
(
e
m
p
l
o
y
e
e
⋈
w
o
r
k
s
⋈
c
o
m
p
a
n
y
)
\prod_{}person\_name (employee \Join works \Join company)
∏ p e r s o n _ n a m e ( e m p l o y e e ⋈ w o r k s ⋈ c o m p a n y ) e.假设公司可以位于几个城市中。找出满足下面条件的所有公司,它位于Small Bank Corporation所位于的每一个城市。
∏
c
o
m
p
a
n
y
_
n
a
m
e
(
c
o
m
p
a
n
y
÷
(
∏
c
i
t
y
(
σ
c
o
m
p
a
n
y
_
n
a
m
e
=
“
S
m
a
l
l
B
a
n
k
C
o
r
p
o
r
a
t
i
o
n
”
(
c
o
m
p
a
n
y
)
)
)
)
\prod_{}company\_name (company ÷(\prod_{}city (\sigma_{company\_name =“Small Bank Corporation”} (company))))
∏ c o m p a n y _ n a m e ( c o m p a n y ÷ ( ∏ c i t y ( σ c o m p a n y _ n a m e = “ S m a l l B a n k C o r p o r a t i o n ” ( c o m p a n y ) ) ) )