由完全外連接產生的關係的鍵
全外連接產生的關係的關鍵是什麼?如果沒有鍵,怎麼說關係代數在它的運算元下是封閉的,每個運算元的結果也是一個關係呢?
簡答
關係代數中的閉包與鍵的概念無關。只要該關係具有以下屬性,關係變數就持有關係:
- 元組沒有順序- 順序沒有隱含意義
- 元組是不同的- 沒有重複
- 屬性沒有順序- 順序沒有隱含意義
- 屬性是單值的——無論它是什麼類型,都只有一個
關係代數的基本運算元確實是封閉的,因此當應用於關係時,總是產生關係。鍵是不相關的,因為根據定義,每個關係都沒有重複的元組。根據定義,任何會導致重複元組的操作(例如,單個屬性在關係上的投影)都會在提供結果時消除那些重複的元組。如您所知,SQL 沒有正確實現這一點。
長答案
為了真正理解簡短的答案,並理解“外連接”給等式帶來的額外細微差別,我們需要深入研究數代數中關係代數的基礎。
數代數
代數是Google定義的“數學的一部分,其中字母和其他通用符號用於表示公式和方程式中的數字和數量”。一個代數屬性是operation,這意味著有一些動作可以改變數字。對於數字,這些是加法、減法、乘法、除法、求冪和求根。還有許多其他代數屬性,例如關聯屬性,它表明您可以以任何方式對數字進行分組,而不會更改運算結果。這些屬性賦予代數獨特的力量,因為有了這些屬性,我們可以使用字母來表示數字,通過方程中定義的運算符來操作它們,並且知道無論最終用什麼實際數字代替字母,轉換都是絕對正確的。
閉包是另一個代數性質,它表明如果對數字起作用的運算符總是產生數字,那麼數字在該運算下是閉合的。例如,我們知道的實數在加法下是封閉的。將任意兩個實數相加,結果將始終是實數。實數在平方根運算下**不閉合,因為 -1 的平方根不是實數。**所有這些都直接來自數學論壇@Drexel的屬性詞彙表。
關係代數
Chris Date 說 Ted Codd 是個天才。Codd 的獨特天才是認識到數學關係與集合論和邏輯相結合,在應用於數據管理時會非常實用。Fabian Pascal 的實用數據庫基礎系列很好地解釋了為什麼會這樣,我將簡要回顧他的一些見解。
1960 年代的主要數據庫問題之一是,必須為每個“問題”編寫程序,以便 DBMS 管理數據。Codd 表明,通過採用關係的概念並將其應用於數據庫,可以開發出完全不同於數據物理儲存方式的數據輸入和輸出邏輯模型。該邏輯模型的一部分是適用於關係的一組運算符 - 關係代數。就像數字代數允許我們利用代數性質來處理大量複雜的方程一樣,其中字母代表任何潛在的數字並保證正確的結果,關係代數也可以對關係做同樣的事情。
為什麼這很重要?因為對於代數,運算及其結果並不取決於關係及其屬性的實際含義。然後,通過調整邏輯,它像代數一樣禁止有效形式,無論命題是什麼意思,這些形式可用於評估論點是真還是假,可以實現一種通用查詢語言,使 DBMS 的使用者能夠詢問真數據問題 - 任意複雜性之一 - 可以使用關係代數規則對 DBMS 進行程式,以給出可證明的正確答案!
現在就像數字代數一樣,閉包是賦予代數權力的基本屬性。關係在基本運算符下是封閉的,因此您可以按任意順序任意嵌套這些操作,以聲明幾乎任何您能想到的“問題”。一旦創建了實現關係代數的 DBMS,就不再需要編寫獨特的程序來找到每個問題的答案。DBMS 使用者只需使用關係代數聲明問題。
外連接
到目前為止,我一直在說基本運算符。那是因為該理論沒有考慮缺失的數據。根據定義,每個關係都包含具有每個屬性值的元組。但是為了使數學適應缺失數據的實際情況,必須為屬性值未知時開發一些解決方案。SQL 實現了 NULL 和 3VL。Codd後來提出了標記和 4VL。必須擴展連接運算符以保留不匹配的元組,並且 SQL 通過為不匹配的元組的屬性生成 NULL 而不是值來實現擴展。日期表明,通過執行此外部連接是:
一種霰彈槍婚姻:它迫使表成為一種聯合——是的,我的意思是聯合,而不是聯合——即使所討論的表不符合聯合的通常要求(參見第 6 章)。實際上,它是通過在執行聯合之前用空值填充一個或兩個表來做到這一點的,從而使它們最終符合那些通常的要求。但是沒有理由不應該使用正確的值而不是空值來完成填充。(日期,CJ (2011-12-16)。SQL 和關係理論:如何編寫準確的 SQL 程式碼(Kindle 位置 2601-2602)。O’Reilly 媒體。Kindle 版。)
結論
那麼在外連接(全、左、右)的操作下,關係是閉合的嗎?我想這取決於該運算符的實現方式。如果您確實認為關係仍然是關係,即使帶有未匹配元組屬性的缺失值的標記,我會說是的。或者是的,如果您不認為一個關係仍然是一個關係,即使有缺失值的標記,但可以用預設值代替缺失的屬性值。但是,如果您認為即使帶有缺失值標記的關係仍然是關係,並且您的 DBMS 實現了 SQL NULL,並且您不能或不將值替換為外部連接中 SQL 提供的 NULL,那麼不,關係是未在該外部聯接下關閉。兩個關係進去了,但是一個關係沒有出來。