数据库基础01-关系代数
我们使用关系代数的运算来从表R和表S中产生新的表,关系代数的运算包括两种:集合运算和自然关系运算
注:只有两个表是兼容表(即两个表的标题完全相同),这两个表才能执行交,并,差运算
下面看栗子
表R
A | B | C |
---|---|---|
a1 | b1 | c1 |
a1 | b2 | c3 |
a2 | b1 | c2 |
表S
A | B | C |
---|---|---|
a1 | b1 | c1 |
a1 | b1 | c2 |
a1 | b2 | c3 |
a3 | b2 | c3 |
那么表R∪S为
A | B | C |
---|---|---|
a1 | b1 | c1 |
a1 | b2 | c3 |
a2 | b1 | c2 |
a1 | b1 | c2 |
a3 | b2 | c3 |
很显然,就是表R和表S中所有行取并集
同样,表R∩S为
A | B | C |
---|---|---|
a1 | b1 | c1 |
a1 | b2 | c3 |
表R-S为
A | B | C |
---|---|---|
a2 | b1 | c2 |
就是表R中去除存在于表S中的行
同样S-R为
A | B | C |
---|---|---|
a1 | b1 | c2 |
a3 | b2 | c3 |
注:由于我们需要简洁地表示产生的表,所以我们可以用赋值运算为产生的新表命名
如 T:=R-S,则产生的新表为表T
下面是乘积运算
表R
A | B |
---|---|
a1 | b1 |
a2 | b2 |
表S
B | C |
---|---|
b1 | c1 |
b2 | c2 |
b3 | c3 |
表RXS
A | R.B | S.B | C |
---|---|---|---|
a1 | b1 | b1 | c1 |
a1 | b1 | b2 | c2 |
a1 | b1 | b3 | c3 |
a2 | b2 | b1 | c1 |
a2 | b2 | b2 | c2 |
a2 | b2 | b3 | c3 |
注意:表R和表S中都有叫做B的列,但是我们不认为他们是一样的,因此使用R.B表明这是表R的B列
RXS其实就是用表R的每一行后面去接上表S的所有行↓
R的第一行 S的第一行
R的第一行 S的第二行
R的第一行 S的第三行
…
R的第二行 S的第一行
…
注:我们不可以使用比如RXR,因为无法分清列名,如果想要用这个,需要先S:=R,然后RXS
下面说投影
投影其实就是把一张表的某一列或者某几列抠出来
表R
A | B | C |
---|---|---|
a1 | b1 | c1 |
a1 | b2 | c3 |
a2 | b1 | c2 |
那么R[A]就是
A |
---|
a1 |
a1 |
a2 |
R[A, C]就是
A | C |
---|---|
a1 | c1 |
a1 | c3 |
a2 | c2 |
关于选择运算
S where C
C指condition条件,这个运算会把表S里所有满足条件C的行全部拿出来,然后组装成一张表
C可以是比较条件,比如>,<,=,>=,<=,<>(注:<>指“不等”),如R where A <> a2 指把表R中 所有A列上的值不等于a2 的行(即第一行和第二行)拿出来组成新的表
注:这里用=表示等于而不是用==
C也可以是多个条件C1,C2的运算,如C1 AND C2, C1 OR C2, NOT C1
连接
连接运算干的事情就是把两个表连成一个表
具体如下:
表R
A | B1 | B2 |
---|---|---|
a1 | b1 | b1 |
a1 | b2 | b1 |
a2 | b1 | b2 |
表S
B1 | B2 | C |
---|---|---|
b1 | b1 | c1 |
b1 | b1 | c2 |
b1 | b2 | c3 |
b2 | b2 | c4 |
则表R JOIN S为
A | B1 | B2 | C |
---|---|---|---|
a1 | b1 | b1 | c1 |
a1 | b1 | b1 | c2 |
a2 | b1 | b2 | c3 |
很显然,表R和表S根据相同的列B1,B2相连,R中的任何一行,和S中的任何一行,如果他们的[B1, B2]完全相同,那么这两行就可以连起来,成为新表中的一行
除
表R
A | B | C |
---|---|---|
a1 | b1 | c1 |
a2 | b1 | c1 |
a1 | b2 | c1 |
a1 | b2 | c2 |
a2 | b1 | c2 |
a1 | b2 | c3 |
a1 | b2 | c4 |
a1 | b1 | c5 |
表S1
C |
---|
c1 |
表R÷S1
A | B |
---|---|
a1 | b1 |
a2 | b1 |
a1 | b2 |
表S2
C |
---|
c1 |
c2 |
表R÷S2
A | B |
---|---|
a1 | b2 |
a2 | b1 |
除法运算R÷S干的事情就是
以R÷S2为例:为什么新表中有a1 b2行,因为表R中有这样两行
A | B | C |
---|---|---|
a1 | b2 | c1 |
a1 | b2 | c2 |
为什么新表中有 a2 b1行,因为表R中有这样两行
A | B | C |
---|---|---|
a2 | b1 | c1 |
a2 | b1 | c2 |
下面是一些运用的栗子
现在考虑如下含有4张表(C, A, P, O)的数据库
1.查询所有订购了至少一个价格为$0.5的商品的顾客的名字
价格为0.5的商品的pid:(P where price = 0.5)[pid]
然后在表O中找出有这些pid的行
答案:((P where price = 0.5)[pid] JOIN O)[cname]
2.查询全部没有在代理商a03处订购商品的顾客的cid
在a03处订购商品的顾客cid为:(O where aid = ‘a03’)[cid]
因此,答案为:C[cid] - (O where aid = ‘a03’)[cid]
3.查询只在代理商a03处订购商品的顾客的cid
在其他代理商处订购商品的顾客的cid为:(O where aid <> ‘a03’)[cid]
答案:O[cid] - (O where aid <> ‘a03’)[cid]
4.查询没有被任何一个在New York的顾客通过在Boston的代理商订购的所有商品
在New York的顾客的cid:(C where city = ‘New York’)[cid]
在Boston的代理商的pid:(A where city = ‘Boston’)[pid]
把这两个表和表O相连即可
答案:P[pid] -(((C where city = ‘New York’)[cid] JOIN O) JOIN (A where city = ‘Boston’)[pid])
5.查询订购了所有的价格为0.5的商品的顾客名字
价格为0.5的商品的pid:(P where price = 0.5)[pid]
答案:((O[cid, pid] ÷ (P where price = 0.5)[pid]) JOIN C)[cname]
注:“所有” ==> ÷