天天看點

《SQL與關系資料庫理論——如何編寫健壯的SQL代碼》一一2.5 标量類型vs.非标量類型

本節書摘來華章計算機《sql與關系資料庫理論——如何編寫健壯的sql代碼》一書中的第2章 ,第2.5節 c. j. date 著 單世民 何英昊 許侃 譯 更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視。

通常,都會認為類型不是标量的就是非标量的。換言之,如果一個類型沒有使用者可見的分量,那麼它就是标量的;否則它就是非标量的。某個類型t的值、變量、屬性、運算符、參數及表達式是否是标量的,取決于類型t本身是否是标量的。例如:

整數類型是标量類型,是以,整數類型的值、變量等也都是标量的,即它們沒有使用者可見分量。

元組和關系類型是非标量的(相關的使用者可見分量是對應的屬性)。是以,元組和關系值、變量等也都是非标量的。

必須強調,這些概念是相當不嚴格的。實際上,我們已經看到資料值原子性的概念本就沒有什麼絕對的含義,那麼“标量”本身也隻不過是同一概念的另一名稱罷了。是以,在任何正式意義上,關系模型都不會依賴于标量與非标量的差別。然而,在本書中要非正式地依賴它。我發現它直覺上非常有用。具體說,對于既不是元組也不是關系的類型,使用術語标量;而對于元組或關系類型,使用術語非标量。注12

旁注:你有時會聽到另一個表示“标量”的術語是封裝(encapsulation)。然而要小心,這個術語也被(尤其在對象上下文中)用來指對代碼和資料(更準确地是運算符定義和資料表示定義)的實體捆綁或打包。但是若使用了後面這種意義,就混淆了模型和實作,顯然使用者并不關心也不必關心代碼和資料到底是實體綁定在一起的還是分離的。

我們來看一個例子。下面是tutorial d對于基關系變量 s(supplier)的定義。注意,為了簡化,我将所有的屬性都定義為某種系統定義類型:

解釋:

第1行中的關鍵字var表示此句為一個變量的定義;s是變量的名稱,關鍵字base特别指出變量是一個基關系變量。

第2行指定變量的類型。關鍵字relation說明它是一個關系類型。此行的剩餘部分指定構成對應關系标題的屬性集合(在第1章中,一個屬性定義為一個“屬性-名稱”/“類型-名稱”對,并且在标題中沒有兩個屬性具有相同的屬性名稱)。當然,類型是非标量類型。屬性的順序并不重要。

第3行定義{sno}是這個關系變量的(候選)鍵。

事實上,這個例子也講解了另一要點,即下述類型是一個生成式類型的示例。

一個生成式類型是通過調用某些類型生成器(type generator)獲得的類型(此例中,類型生成器就是relation)。你可以認為一個類型生成器是一種特殊類型的運算符;它之是以特殊是因為:(a)它傳回一個類型而不是一個值;(b)它在編譯期被調用而不是在運作時被調用。比如,大部分程式設計語言都支援名為array的類型生成器,可以讓使用者定義各種特定的數組類型。然而,我們現在關心的類型生成器是tuple和relation。下面是一個包含tuple類型生成器的示例:

在任何時刻變量stv的取值都是一個标題與關系變量s的标題相同的元組(我特意指定了不同的屬性順序,就是為了說明次序并不重要)。注13是以,我們可以設想一個代碼片段:(a)從關系變量s目前取值中抽取一個“一-元組”關系(可能這個關系就包含一個針對供應商s1的元組);(b)從那個“一-元組”關系中抽取單一的元組;(c)将抽取出的元組指派給變量stv。在tutorial d中:

重點:我可不想讓你在這裡産生誤解。盡管某些存取suppliers-and-parts資料庫的應用程式需要stv這樣的變量,但在資料庫内部不可以出現這樣的變量。一個關系資料庫隻包含一種變量,即關系變量(relvars)。換句話說,關系變量是關系資料庫中唯一允許存在的變量類型。(後面提到——關系變量是關系資料庫中允許存在的唯一變量類型——構成了資訊原理(information principle)。附錄a中将進行更詳細的說明)。

另外,要特别注意的是(如前例所示)一個元組t和一個僅僅包含元組t的關系r是存在邏輯差異的。尤其是,它們屬于不同類型——t是某個元組類型而r是某個關系類型(盡管這些類型确實有一樣的屬性标題,或者說有相同的屬性)。

最後,以下内容為其他要點:

盡管元組和關系類型都有使用者可見分量(即它們的屬性),但并不是說這些分量也必須進行同樣的實體存儲。實際上,元組及關系的實體表示應該對使用者是掩藏的,就好像标量值一樣。(參考第1章中對于實體資料獨立性的讨論。)

類似于标量類型,元組和關系類型肯定需要與其關聯的選擇器運算符(字面值是特例)。下一章将詳細說明。不過,它們并不需要the_運算符;替代的,它們有對相應屬性進行存取的運算符,這些運算符的角色相當于the_運算符之于标量類型。

元組和關系類型還需要指派和相等比較運算符。本節已經給出了元組指派的示例;下一章會對其他的運算符進行詳細說明。