本節書摘來自異步社群出版社《你不可不知的關系資料庫理論》一書中的第14章,第14.2節,作者:【美】c.j.date,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。
此部分列出了sql與關系模型的不同點,主要是為了參考,同時順便進行一些附加說明。我知道可能會有人對清單中的個别術語吹毛求疵,一一解釋清單中這些特性是非常不容易的,特别是它的正交性(例如,保證這些特性都互相獨立,互不影響)。但是我認為這些吹毛求疵都不是重要的,重要的是它們累積起來造成的影響,坦率地說是相當驚人的3。
不再啰嗦了,下面具體來看一下它們的不同點:
sql不能夠完全區分表的值和表變量。
sql表與關系(或關系變量)不同,因為它們不允許或不需要(根據具體情況而定):(a)重複的行;(b)空值;(c)從左到右有序排列的列;(d)無名的列;(e)重複的列名;(f)指針(雖然标準中沒有,但至少在某種産品中存在);(g)隐藏的列。注意:(a)、(b)、(c)、(f)都代表破壞了資訊準則。(d)和(e)(即無名的列和重複的列名)可能發生在評價某個表達式後得到的結果表中,不能出現在基表或者視圖中。是以嚴格說來,如果我們遵守資訊準則的規定(參見第7章),那麼(d)和(e)的情況就不會破壞它,因為這樣的表就不會出現在資料庫中。但奇怪的是,sql允許我們可以得到不直接存回到資料庫基表中的結果。是以,我認為(d)和(e)肯定會破壞資訊準則(你可能不會相信)。
sql沒有恰當的表辨別符。最接近于這種結構的表示方式是values表達式(順便說一下,處于某種特定的目的,準許或者篡改是經常使用的術語),這樣的表達式就不能用在必須使用辨別符的環境中。(對此,可以參見本章練習14.2。)
sql通常認為視圖不是表。下面這段文字摘自sql and relational theory,但稍微進行了修改:
sql标準,以及其他大多數的sql文檔通常都讨論了術語“表和視圖”(事實上,是相當普遍的)。顯然,采用此種方式讨論的人受到了“表和視圖不同”的影響,認為“表”就是基本表,基本表是實體存儲的,而視圖不是實體存儲的。但總的來說,視圖就是表(或者我更願意把它稱為關系變量)。也就是說,對規則的關系變量(至少是關系模型)執行的運算,在視圖上都可以執行,因為視圖就是“規則的關系變量。”
從數學的角度來說,子集就是集合。實際上,基于集合理論的操作結果得到的就是集合。這個觀點同樣适用于關系模型,任何關系型表達式的操作結果就是關系,特别是對于定義視圖的表達式也是如此。是以,認為sql中的視圖不同于表的那些人是沒有從關系的角度考慮問題,這有可能會引發一些錯誤。
sql表(從前面的叙述來看,要包括視圖!)至少包含1列。對于該點的解釋,請參照附錄b(這裡也說明了sql不完全是關系型的)。
sql沒有顯式的表指派運算符。
sql當然也沒有顯式的多變量表指派運算(也沒有類似的insert/delete/update操作)。
sql在很多方面都破壞了指派規則(the assignment principle),有一些是處理空值的(有一些是處理字元串類型的,還有一些是處理“可能的沒有确定值的”表達式)。
sql在很多方面都破壞了黃金規則(the golden rule),其中包括處理空值的,特别是推遲進行完整性檢測方面。
sql沒有合适的“表類型”定義。
sql沒有表之間的“=”運算,實際上,它根本不執行表之間的比較運算。
sql允許把合适的超碼顯式聲明為碼。
sql的并、交、聯接運算不滿足交換律。
sql的并、交、聯接運算不滿足等幂性。
sql的并運算不是聯接運算的特例(重複值和空值的存在是罪魁禍首)。
sql中沒有明确定義聯接運算(原因是sql表的内容是一組行的包,而不是集合)。
sql沒有适當的聚集運算符。
sql在處理空集時會産生各種邏輯錯誤,包括文法和語義方面的邏輯錯誤。
很多sql表的表達式都是“可能具有未确定值的”。
sql支援各種行級的運算符(如遊标的修改、行級的觸發器等)。
雖然在sql的标準中沒有提供,但是某種特定的商業産品中使用的sql專業術語有時确實會涉及實體級的構成(例如,索引)。
sql的視圖定義中包括映射資訊以及結構化資訊4。>{注意:}針對該點及下一點重要性的詳細讨論可參見我的一本專著:view updating and relational theory: solving the view update problem(2013年,o’reilly出版)。
sql對于視圖修改的支援是很薄弱的、針對特定問題的、不完整的。
sql不能正确區分類型與描述之間的關系。(這個問題主要發生在sql的子類型機制中,但不排除其他情況,詳細讨論已經超出本書的範圍。)
sql不支援類型限制。
sql的“結構化類型”有時被封裝起來,有時卻未被封裝。>{注意:}結構化類型是sql用來自定義類型的一種機制。詳細讨論也超出本書的範圍。
sql不能正确區分類型和類型發生器。
雖然sql标準中支援boolean類型,但大多數商業化産品卻不支援該類型。
sql對于“=”的支援是存在嚴重缺陷的。具體來講,“=”可以(a)比較的兩個數明顯不同,但也可以得到true;(b)兩個比較的數沒有明顯差異,卻不能得到true;(c)是以可以使用者自定義,是以在語義上存在二義性(特别是使用者自定義類型中);(d)根本不支援定義xml類型;(e)雖然在标準中沒有說明,但在一些特定的産品中也不支援一些特定的類型(如blob和clob)。
sql是基于3-值邏輯的(可以這樣說),但關系模型是基于2-值邏輯的。
如前所述,sql不完全是關系型的。
sql不直接支援映像關系,也不支援rename、xunion(排他型并運算)、matching、not matching、d_union、i_minus、d_insert、i_delete。還有其他的未在本書讨論的關系運算符。
上述列出的條目并不詳盡。