关系数据操作建立在集合运算的基础上,操作的对象和结果都是集合。描述关系数据操作的语言称为关系数据语言。在关系数据库的发展历程中,关系代数、关系演算、结构化查询语言(Structured Query Language,SQL)都是具有代表性的关系数据语言。
关系代数最早由E.F.Codd于1972年提出,其运算的对象和运算的结果都是关系。关系演算则以更微观的元组变量或者域变量作为基本运算对象。结构化查询语言于1974年由Boyce和Chamberlin提出,并在IBM公司研制的关系型数据库管理系统原型System R上实现。与关系代数、关系演算相比,SQL使用方便、功能丰富、语言简洁、容易掌握,这些优点使SQL后来居上,很快SQL就成为了应用最广的关系数据语言。SQL语句的综合性高,而关系代数中的语句功能单一。因此,关系代数中的语句可以看作SQL语句的分解动作,对于初学者而言,学习关系代数将有助于加深对SQL的理解。本章将简单介绍关系代数的基本概念和相关操作,为后面章节学习SQL做铺垫。
关系代数的集合运算分为传统的集合运算和专门的关系运算两种类型。
传统的集合运算包括并、交、差、广义笛卡儿积4种运算。
1. 并(∪)
设关系 R 和关系 S 都有 n 个属性,且相应的属性取自同一个域。对关系 R 与关系 S 进行并(Union)操作,结果仍是一个具有 n 个属性的关系。该关系由关系 R 和关系 S 中的所有元组组成,相同的元组只保存一次,可记作:
R ∪ S ≡{ t | t ∈ R ∨ t ∈ S }
例2-6 如表2-2所示的关系 R 中有两个元组,如表2-3所示的关系 S 中也有两个元组。 R ∪ S 的结果如表2-4所示。
表2-2 关系R
表2-3 关系S
表2-4 R∪S
注意,两个关系中有关张伟的相同元组在结果中只出现一次。
设关系 R 和关系 S 都有 n 个属性,且相应的属性取自同一个域。对关系 R 与关系 S 进行交(Intersection)操作,结果仍是一个有 n 个属性的关系。该关系由既属于关系 R 又属于关系 S 的所有元组组成,可记作:
R ∩ S ≡{ t | t ∈ R ∧ t ∈ S }
例2-7 表2-2的关系 R 和表2-3的关系 S 的交集 R ∩ S 如表2-5所示。
表2-5 R∩S
结果中只有一个关于张伟的元组,因为只有它出现在两个关系中。
3. 差(-)
设关系 R 和关系 S 都有 n 个属性,且相应的属性取自同一个域。对关系 R 与关系 S 进行差(difference)操作,结果仍是一个有 n 个属性的关系。该关系由属于关系 R 且不属于关系 S 的所有元组组成,可记作:
R-S ≡{ t | t ∈ R ∧ t ∉ S }
例2-8 表2-2的关系 R 和表2-3的关系 S 中,只有周萍元组在关系 R 中且不在关系 S 中, R-S 如表2-6所示。
表2-6 R-S
4. 广义笛卡儿积(×)
设关系 R 有 n 个属性,关系 S 有 m 个属性,关系 R 和关系 S 的广义笛卡儿积是一个有( n + m )个属性的关系。该关系的元组由关系 R 的元组和关系 S 的元组两两组合而成,元组的个数为关系 R 和关系 S 元组个数的乘积,可记作:
R × S ≡{( t r , t s )| t r ∈ R ∧ t s ∈ S }
其中, t r 表示关系 R 的一个元组, t s 表示关系 S 的一个元组,( t r , t s )表示由关系 R 的一个元组 t r 和关系 S 的一个元组 t s 前后有序拼接构成广义笛卡尔积 R × S 的一个元组。
例2-9 设关系student和business如表2-7和表2-8所示,其中关系student有5个属性、2个元组,而关系business有2个属性、3个元组,则关系student×business有7个属性,6个元组,如表2-9所示。
表2-7 关系student
表2-8 关系business
表2-9 关系student×business
专门的关系运算包括投影、选择、连接和除4种运算。
设关系 R 和关系 S 都有 n 个属性,且相应的属性取自同一个域。
1. 投影(Π)。
投影(Projection)是根据某些条件对关系进行垂直分割,产生一个只有部分属性的新关系,新关系中的属性可以重新安排顺序。投影运算可记作:
∏ A 1 , A 2 ,…, A n ( R )
其中, A 1 , A 2 ,…, A n 是对关系 R 进行投影运算后保留在新关系中的属性。
例2-10 关系card的元组如表2-10所示。
表2-10 card的元组
如果仅需要查询关系card中CID和balance两个属性的信息,可进行Π CID,balance (card)运算,然后将关系card投影到CID和balance属性上,结果如表2-11所示。
表2-11 Π CID,balance (card)的结果
2. 选择(σ)。
选择(Selection)是根据条件对关系做水平分割,产生一个仅由符合条件的元组构成的新关系。选择运算可记作:
σ F ( R )
其中,F表示选择条件。
例2-11 查询如表2-10所示的关系card中余额不少于300元的校园卡信息。
第一个元组、第二个元组使选择条件balance≥300为假,第三个元组使选择条件balance≥300为真,所以第三个元组在结果中出现。关系card中只有满足选择条件balance≥300的元组被选取,如表2-12所示。
表2-12 σ balance ≥300 (card)的结果
例2-12 查询表2-10关系card中可以正常使用且余额小于300元的所有校园卡的卡号。
该项查询是对同时满足两个条件的复合查询、投影的综合应用。查询结果如表2-13所示。
表2-13 Π CID ( σ balance<300 AND state='0' (card))的结果
3. 连接 。
连接(Join)是从两个关系的笛卡儿乘积中选取属性间满足特定条件的元组,可记作:
其中, F 表示连接条件。如果连接条件中使用“=”作为连接运算符,将从两个关系的笛卡儿乘积中选取公共属性的取值相等的元组构成新的关系,则该连接运算称为等值连接(Equal Join),可记为
例2-13 关系student和card的元组如表2-14和表2-15所示。
Π name, CID (student) student.CID=card.CID Π CID, balance (card)的结果如表2-16所示。
表2-14 关系student的元组
表2-15 关系card的元组
表2-16 Π name, CID (student) student.CID=card. CID Π CID, balance (card)的结果
student和card的公共属性是CID,在等值连接的结果中重复出现而且取值相同,应该进行优化。
自然连接(Natural Join)是一种特殊的等值连接,会去掉等值连接中重复的属性,在语法格式中省略等值连接条件,可记为
在Π name, CID (student) Π CID, balance (card)的结果中,公共属性CID只保留了一个,如表2-17所示。
表2-17 Π name, CID (student) Π CID, balance (card)的结果
4. 除(÷)。
设关系 R 和 S 具有公共属性(或属性组),公共属性(或属性组)用 Y 表示,独有的非公共属性(或属性组)分别用 X 和 Z 表示,则两个关系可以表示为 R ( X , Y )和 S ( Y , Z )。公共属性 Y 可以有不同的属性名,但必须具有相同的域。 R 与 S 的除(division)运算可得到一个新的关系,该关系只有 X 属性,由 R 中满足下列条件的元组在 X 上的投影构成:关系 R 中的元组在 X 上分量值 x 的象集 Y x 包含 S 在 Y 上投影的集合,可记作:
R ÷ S ={ t r [ X ]| t r ∈ R ∧Π Y ( S )⊆ Y x }
其中, Y x 为 x 在 R 中的象集, x = t r [ X ]。
例2-14 查询至少在第一食堂、百景园餐厅都消费过的校园卡卡号。
该查询要用到关系salebill和business(如表2-18和表2-19所示),并且要用到关系代数的除运算。
表2-18 salebill
表2-19 business
先建立一个关系 S ,包含要查询的商户编号BID,运算结果如表2-20所示。
以此表为除数,求解满足条件的卡号,查询结果如表2-21所示。
表2-20 ΠBID(σname='第一食堂'OR name='百景园餐厅 ' (business))的结果
表2-21 Π CID,BID (salebill)÷Π BID (σ name= ' 第一食堂 ' OR name='百景园餐厅'(business))的结果
结果为什么是C00002、C00003呢?关系salebill中不同的CID在BID上的象集如表2-22所示。
表2-22 salebill中不同的CID在BID上的象集
其中,校园卡C00002、C00003在BID上的象集包含{B001,B003};其他CID在BID上的象集都不包含{B001,B003}。所以满足查询条件的是校园卡C00002、C00003。