前面介紹了關(guān)系模型主體結(jié)構(gòu)玄括。關(guān)系模型的另一重要組成部分是操作機(jī)制分瘦,或者說(shuō)是 查詢語(yǔ)言,它負(fù)責(zé)基礎(chǔ)數(shù)據(jù)的檢索與更新食铐。下面將重點(diǎn)分析關(guān)系模型的查詢語(yǔ)言,重點(diǎn)對(duì)關(guān)系代數(shù)和關(guān)系演算進(jìn)行討論僧鲁,Codd 在 1971 年將它們定義為關(guān)系語(yǔ)言的基礎(chǔ)虐呻。不嚴(yán)格的說(shuō),可以將關(guān)系代數(shù)描述為一種(高級(jí)的)過(guò)程式語(yǔ)言寞秃,即可用它告訴 DBMS 如何從數(shù)據(jù)庫(kù)的一個(gè)或多個(gè)關(guān)系中構(gòu)建新關(guān)系斟叼;而將關(guān)系演算看成是一種非過(guò)程式語(yǔ)言,它用公式給出由數(shù)據(jù)庫(kù)中一個(gè)或多個(gè)關(guān)系構(gòu)成的新關(guān)系的定義春寿。然而朗涩,關(guān)系代數(shù)與關(guān)系演算形式上是互相等價(jià)的,即每個(gè)關(guān)系代數(shù)表達(dá)式都有一個(gè)等價(jià)的關(guān)系演算表達(dá)式與之相對(duì)應(yīng)(反之亦然)绑改。
演算與代數(shù)都是形式語(yǔ)言谢床,對(duì)用戶不太友好。它們通常用作其他高級(jí)關(guān)系數(shù)據(jù)庫(kù)數(shù)據(jù)操作語(yǔ)言(Data Manipulation Language, DML)的基礎(chǔ)厘线。人們之所以對(duì)它們感興趣识腿,是因?yàn)樗鼈冴U述了每種數(shù)據(jù)操作語(yǔ)言所需的基本操作,而且它們是其他關(guān)系語(yǔ)言之間相互比較的標(biāo)準(zhǔn)造壮。
關(guān)系演算用來(lái)衡量關(guān)系語(yǔ)言的選擇能力渡讼。如果一種語(yǔ)言可以生成所有由關(guān)系演算推導(dǎo)出來(lái)的關(guān)系,就稱它具有關(guān)系完備性费薄。大多數(shù)關(guān)系查詢語(yǔ)言都具有關(guān)系完備性硝全,但它們比關(guān)系代數(shù)或關(guān)系演算更具表達(dá)能力栖雾,因?yàn)樗鼈兺ǔ_€附加了完成計(jì)數(shù)楞抡、求和以及排序等功能的操作。
關(guān)系代數(shù)
關(guān)系代數(shù)是一種純理論語(yǔ)言析藕,它定義了一些操作召廷,運(yùn)用這些操作可以從一個(gè)或多個(gè)關(guān)系中得到另一個(gè)關(guān)系,而不改變?cè)P(guān)系账胧。因此竞慢,它的操作數(shù)和操作結(jié)果都是關(guān)系,而且一個(gè)操作的輸出可以作為另一個(gè)操作的輸入治泥。故而關(guān)系代數(shù)的一個(gè)表達(dá)式中可以嵌套另一個(gè)表達(dá)式筹煮,就像算術(shù)運(yùn)算一樣。這種性質(zhì)稱為閉包居夹。
- 閉包(closure):關(guān)系在關(guān)系代數(shù)下是封閉的败潦,正如數(shù)在算術(shù)運(yùn)算下是封閉的一樣本冲。
關(guān)系代數(shù)是一種每次一關(guān)系(或集合)的語(yǔ)言,即用一條不帶循環(huán)的語(yǔ)句處理劫扒,結(jié)果也是由所有元組組成的整個(gè)關(guān)系檬洞,當(dāng)然,結(jié)果關(guān)系中的元組可能來(lái)自參與運(yùn)算的多個(gè)關(guān)系沟饥。關(guān)系代數(shù)運(yùn)算的語(yǔ)法形式有好幾種添怔,這里采用了一套通用的符號(hào)表示方法,但并沒(méi)有進(jìn)行嚴(yán)格的形式定義贤旷。
關(guān)系代數(shù)中包含了許多運(yùn)算广料。Codd (1972a)首先提出了八個(gè)運(yùn)算,現(xiàn)在又發(fā)展了一些其他的運(yùn)算幼驶。關(guān)系代數(shù)中有五個(gè)基本運(yùn)算性昭,即選擇、投影县遣、笛卡爾積糜颠、集合并、集合差萧求,它們能實(shí)現(xiàn)大多數(shù)人們感興趣的數(shù)據(jù)檢索操作其兴。此外,還有連接夸政、集合交元旬、除運(yùn)算等,它們都可以通過(guò)五個(gè)基本運(yùn)算表示出來(lái)守问。
這其中選擇和投影運(yùn)算都是一元運(yùn)算匀归,因?yàn)樗麄冎粚?duì)一個(gè)關(guān)系進(jìn)行運(yùn)算。其他的運(yùn)算則是作用在兩個(gè)關(guān)系上耗帕,因此稱為二元運(yùn)算穆端。在下面給出的定義中,R 和 S 代表兩個(gè)關(guān)系仿便,它們分別定義了屬性:
1.一元運(yùn)算
先來(lái)討論關(guān)系代數(shù)中的兩個(gè)一元運(yùn)算:選擇和投影体啰。
-
選擇(或限制):選擇運(yùn)算作用于單個(gè)關(guān)系 R,得到一個(gè)新關(guān)系嗽仪,它由 R 中滿足特定條件(謂詞荒勇,predicate)的元組組成。通常表達(dá)式像下面這樣:
選擇運(yùn)算舉例:
列出工資多于 10000 英鎊的所有員工闻坚。
這個(gè)例子中沽翔,輸入關(guān)系是 Staff,謂詞是 salary > 10000窿凤。通過(guò)選擇運(yùn)算定義了一個(gè)新的關(guān)系仅偎,它只包括關(guān)系 Staff 中工資多于 10000 英鎊的元組西潘。這個(gè)運(yùn)算的結(jié)果如下圖所示∩谒蹋可以運(yùn)用邏輯運(yùn)算符與喷市、或、非來(lái)生成更為復(fù)雜的謂詞威恼。
-
投影:投影運(yùn)算作用于單個(gè)關(guān)系 R品姓,得到由 R 的一個(gè)垂直子集構(gòu)成的新關(guān)系,該垂直子集抽取 R 中指定屬性上的值并丟掉了重復(fù)元組箫措。通常表達(dá)式像下面這樣:
投影運(yùn)算舉例:
產(chǎn)生僅顯示 staffNo腹备、fName、lName 和 salary 信息的員工工資列表斤蔓。
在這個(gè)例子中植酥,投影運(yùn)算定義了一個(gè)新的關(guān)系,它只包含 Staff 關(guān)系中指定的 staffNo弦牡、fName友驮、lName 和 salary 屬性,并以指定的順序排列這些屬性驾锰。
2.集合運(yùn)算
選擇和投影運(yùn)算都只是從單個(gè)關(guān)系中提取信息卸留。顯然還會(huì)遇到這樣的狀況,需要結(jié)合多個(gè)關(guān)系中的信息椭豫。
-
并:兩個(gè)關(guān)系 R 和 S 的并耻瑟,定義了一個(gè)包含 R、S 中所有不同元組的新關(guān)系赏酥。R 和 S 必須具有并相容性喳整。
-
集合差:集合差運(yùn)算定義了一個(gè)新的關(guān)系,它由所有屬于 R 但不屬于 S 的元組構(gòu)成裸扶。R 和 S 必須具有并相容性框都。
-
交:交運(yùn)算定義了一個(gè)關(guān)系,它由既屬于 R 又屬于 S 中的元組構(gòu)成姓言。R 和 S 必須具備并相容性瞬项。
-
笛卡爾積:笛卡爾積運(yùn)算定義了一個(gè)關(guān)系,它是關(guān)系 R 中每個(gè)元組與關(guān)系 S 中每個(gè)元組并聯(lián)的結(jié)果何荚。
分解復(fù)雜運(yùn)算
關(guān)系代數(shù)運(yùn)算可以變得相當(dāng)復(fù)雜。實(shí)際使用時(shí)猪杭,可將這樣的運(yùn)算分解成一系列較為簡(jiǎn)單的關(guān)系代數(shù)運(yùn)算餐塘,并為每個(gè)中間表達(dá)式的結(jié)果命名。一般通過(guò)賦值運(yùn)算(用符號(hào)←表示)給關(guān)系代數(shù)運(yùn)算的結(jié)果命名皂吮。這與一般編程語(yǔ)言中的賦值運(yùn)算類似:將運(yùn)算符右邊的值賦給左邊戒傻。
此外税手,還可以使用重命名運(yùn)算,它能夠?qū)﹃P(guān)系代數(shù)的運(yùn)算結(jié)果命名需纳。重命名允許將新關(guān)系中的每個(gè)屬性名替換成指定的名稱芦倒。
-
重命名運(yùn)算:重命名運(yùn)算給表達(dá)式 E 提供了一個(gè)新的名稱 S,并將屬性的名稱替換成a1,a2, ... ,an不翩。
3. 連接運(yùn)算
通常只需要將滿足特定條件的笛卡爾積結(jié)合起來(lái)兵扬,因此一般采用連接運(yùn)算來(lái)代替笛卡爾積。連接運(yùn)算是將兩個(gè)關(guān)系結(jié)合起來(lái)組成一個(gè)新的關(guān)系口蝠,它是關(guān)系代數(shù)中一種重要的運(yùn)算器钟。連接是由笛卡爾積導(dǎo)出的,相當(dāng)于把連接謂詞看成選擇條件妙蔗,對(duì)兩個(gè)參與運(yùn)算關(guān)系的笛卡爾積執(zhí)行一次選擇運(yùn)算傲霸。連接是 RDBMS 中最難以高效實(shí)現(xiàn)的運(yùn)算之一,并且可能導(dǎo)致關(guān)系系統(tǒng)存在固有的性能問(wèn)題眉反。
連接運(yùn)算有多種形式昙啄,例如:
θ連接、等接(θ連接的特例)寸五、自然連接跟衅、外連接、半連接
-
θ連接:
-
自然連接:自然連接是關(guān)系 R 和 S 在所有公共屬性 x 上的等接烁试。但在得到的結(jié)果中每個(gè)公共屬性僅保留一次雇初,其余刪除。
在連接兩個(gè)關(guān)系時(shí),經(jīng)常會(huì)出現(xiàn)一個(gè)關(guān)系中的某些元組無(wú)法在另一個(gè)關(guān)系中找到匹配元組的情況支示,換句話說(shuō)刊橘,就是這些元組在連接屬性上不存在匹配值。但可能扔希望這些元組出現(xiàn)在結(jié)果中颂鸿,這時(shí)就要用到外連接促绵。
-
外連接:(左)外連接是這樣一種連接,它將 R 中的所有元組都保留在結(jié)果關(guān)系中,包括那些公共屬性與 S 不匹配的败晴,不過(guò)浓冒,結(jié)果關(guān)系中來(lái)自 S 的所有非公共屬性均取空。
-
半連接:半連接運(yùn)算定義的關(guān)系包含 R 中的這樣一些元組尖坤,它們參與了 R 與 S 滿足謂詞 F 的連接稳懒。
4. 除法運(yùn)算
除法運(yùn)算對(duì)于某些特殊類型的查詢十分有用,這種查詢經(jīng)常出現(xiàn)在數(shù)據(jù)庫(kù)應(yīng)用當(dāng)中慢味。假設(shè)關(guān)系 R 定義在屬性集合 A 上场梆,關(guān)系 S 定義在屬性集合 B 上,并且 B 包含于 A(B 是 A 的子集)贮缕。C = A - B辙谜,即 C 是屬于 R 但不屬于 S 的屬性集合。接下來(lái)給出除法運(yùn)算的定義感昼。
-
除法運(yùn)算:除法運(yùn)算定義了屬性集合 C 上的一個(gè)關(guān)系装哆,該關(guān)系的元組與 S 中 每個(gè) 元組的組合都能在 R 中找到匹配元組。
5. 聚集運(yùn)算和分組運(yùn)算
除了簡(jiǎn)單的獲取一個(gè)或多個(gè)關(guān)系中的元組和屬性外定嗓,我們還希望對(duì)數(shù)據(jù)進(jìn)行匯總和 聚集 運(yùn)算蜕琴,這類似于報(bào)表底部的合計(jì),或是對(duì)數(shù)據(jù)進(jìn)行分組運(yùn)算宵溅,這類似與報(bào)表中的小計(jì)凌简。前面說(shuō)的那些關(guān)系代數(shù)運(yùn)算均不能完成這兩項(xiàng)功能,所以還需要另外的一些運(yùn)算恃逻,如下所述雏搂。
-
聚集運(yùn)算:將聚集函數(shù)列表 AL 用于關(guān)系 R,以獲得在聚集列表上定義的一個(gè)關(guān)系寇损。AL 包含一個(gè)或多個(gè)(<聚集函數(shù)>凸郑,<屬性>)對(duì)。
- COUNT:返回相關(guān)聯(lián)屬性值的個(gè)數(shù)矛市。
- SUM:返回相關(guān)聯(lián)屬性值的總和芙沥。
- AVG:返回相關(guān)聯(lián)屬性值的平均值。
- MIN:返回相關(guān)聯(lián)屬性值的最小值浊吏。
- MAX:返回相關(guān)聯(lián)屬性值的最大值而昨。
-
分組運(yùn)算:根據(jù)分組屬性 GA 對(duì)關(guān)系 R 的元組進(jìn)行分組,然后使用聚集函數(shù)列表 AL 得到新關(guān)系找田。AL 包含一個(gè)或多個(gè)(<聚集函數(shù)>歌憨,<屬性>)對(duì)。結(jié)果關(guān)系包含分組屬性 GA午阵,以及每個(gè)聚集函數(shù)的結(jié)果躺孝。
分組運(yùn)算的一般形式如下: 同一組中的所有元組在屬性 a1, a2, ... ,an 上具有相同的值于个。
不同組中的元組在屬性 a1, a2, ... ,an 上具有不同的值。