規範化數據庫中的異常更新
我一直在嘗試理解數據庫的三種第一種正常形式,但似乎遺漏了一些東西:
想像一個數據庫,其中一張表由舞蹈組成。有5個屬性:
舞蹈#,男舞者姓名,男舞者出生日期,女舞者姓名,女舞者出生日期
不同人的名字可以相同,但我們假設沒有人有相同的名字和相同的生日。同一對舞者可以跳多次。
範例數據庫可能如下所示:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + + + + + + + Dance# + MaleDancerName + MaleDancerDoB + FemaleDancerName + FemaleDoB + + + + + + + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * * * * * * * 1 * Brown * 3/7/1989 * Cortez * 5/2/1983 * * * * * * * **************************************************************************** * * * * * * * 2 * Howard * 7/5/1978 * Taylor * 8/12/1990 * * * * * * * **************************************************************************** * * * * * * * 3 * Brown * 1/4/1986 * Taylor * 8/12/1990 * * * * * * * **************************************************************************** * * * * * * * 4 * Meyer * 2/1/1984 * Andrews * 11/10/1988 * * * * * * * **************************************************************************** * * * * * * * 5 * Brown * 3/7/1989 * Cortez * 5/2/1983 * * * * * * * ****************************************************************************
Dance# 是主鍵 - 也是唯一的候選鍵。
現在,據我所知,這個數據庫是前三種範式:
1. 範式: 是:數據是原子的。
2. 範式:是:沒有非主屬性依賴於任何候選鍵的任何真子集。(表的非主屬性是不屬於表的任何候選鍵的屬性。只有一個候選鍵,Dance#,它沒有子集)
3. 範式: 是:表中的所有屬性僅由候選鍵確定(只有其中一個,Dance#),而不是由任何非主屬性確定。舞者的名字並不能決定出生日期——例如,Dance1 中的 Brown 和 Dance3 中的 Brown 不是同一個人,他們有不同的出生日期。
現在,雖然這張表是所有三種正常形式,但它有更新異常:如果我們發現 Dancer Taylor 實際上出生於 1990 年 9 月 12 日,我們必須在 Dance#2 和 Dance#3 中更正此資訊。
一個明顯的解決方案是將桌子分成兩張桌子,一張給舞者,一張給舞蹈。
但是,僅查看 Normal Forms,該表似乎還可以。
我在哪裡弄錯了嗎?
規範化是通過採用投影來從關係中刪除冗餘的正式過程,這些投影在連接時形成原始關係,從而消除一些冗餘而不會失去數據。它是數據庫設計的基礎科學。前三個範式和 BCNF 通過確保每個非平凡的函式依賴完全依賴於候選鍵來專門處理消除冗餘。更高的範式處理其他類型的依賴關係以進一步消除冗餘。即使完全正規化(5NF 通常被認為是“最終”範式,儘管文獻中還有其他四種)冗餘仍然可以保留,因為並非所有冗餘都可以通過預測來消除。
另一個消除冗餘的工具是正交設計原則,它指出兩個不同的 relvar 不能在其中包含具有以下屬性的元組:如果它出現在第一個 relvar 中,它也必須出現在第二個 relvar 中,反之亦然。但是這個原則只解決了relvar 之間的冗餘,而規範化解決了它們內部的冗餘,所以它對你的例子沒有幫助。
最終,Date 認為我們只需要更多的科學來指導數據庫設計,因為我們今天所展示的還不夠。您的範例的一個實際要點是,儘管存在冗餘,但如果定義一個表來保存所有關鍵的舞者,則至少可以控制冗餘,其中包含姓名和出生日期。然後,姓名和出生日期成為舞蹈表的外鍵,並且可以定義該外鍵以進行級聯更新。然後,如果發現特定舞者的生日有誤並更正,DBMS將自動處理更新舞蹈表中列出該舞者的所有位置。將冗餘的控制權從使用者轉移到系統是向前邁出的一大步,您可以使用今天的 SQL DBMS’。
所有這些資訊都是從 Date 的優秀書籍Database Design and Relational Theory中轉述的,該書就這個問題提供了大量的思考和細節。確實,我們站在巨人的肩膀上。