第三部分 - 數(shù)據(jù)庫分析與設(shè)計(jì) - 5 - 規(guī)范化

為企業(yè)設(shè)計(jì)數(shù)據(jù)庫時(shí),主要目標(biāo)是正確的表示數(shù)據(jù)、數(shù)據(jù)之間的聯(lián)系以及與企業(yè)業(yè)務(wù)相關(guān)的數(shù)據(jù)約束。為了實(shí)現(xiàn)這個(gè)目標(biāo),我們可以使用一種或多種數(shù)據(jù)庫設(shè)計(jì)技術(shù)。前面講了實(shí)體 - 聯(lián)系(ER)建模。下面將講述另一種數(shù)據(jù)庫設(shè)計(jì)技術(shù)——規(guī)范化。

規(guī)范化 是一種數(shù)據(jù)庫設(shè)計(jì)技術(shù),從分析屬性之間的聯(lián)系(即函數(shù)依賴)入手。屬性刻畫了企業(yè)重要數(shù)據(jù)的特性或者這些數(shù)據(jù)之間聯(lián)系的特性。規(guī)范化使用一系列測(cè)試(描述為范式)幫助我們確定這些屬性的最佳組合,最終生成可支持企業(yè)數(shù)據(jù)需求的一組適當(dāng)關(guān)系。

本篇主要目標(biāo)是介紹函數(shù)依賴的概念,并且討論如何將關(guān)系規(guī)范化到第三范式。下一篇還將給出函數(shù)依賴的形式化描述以及比 3NF 更高的范式。

1. 規(guī)范化的目的

規(guī)范化(normalization):生成一組既具有所期望的特性又能滿足企業(yè)數(shù)據(jù)需求的關(guān)系的技術(shù)。

進(jìn)行規(guī)范化的目的是確定一組合適的關(guān)系以支持企業(yè)的數(shù)據(jù)需求。所謂合適的關(guān)系,應(yīng)具有如下性質(zhì):

  • 屬性的個(gè)數(shù)最少,且這些屬性是支持企業(yè)的數(shù)據(jù)需求所必需的。
  • 具有緊密邏輯聯(lián)系(描述為 函數(shù)依賴)的諸屬性均在同一關(guān)系中。
  • 最少 的冗余,即每個(gè)屬性僅出現(xiàn)一次,作為外部關(guān)鍵字的屬性除外。連接相關(guān)關(guān)系必須用到外部關(guān)鍵字。

數(shù)據(jù)庫擁有一組合適的關(guān)系的好處是:數(shù)據(jù)庫易于用戶訪問,數(shù)據(jù)易于維護(hù),在計(jì)算機(jī)上占有較小的存儲(chǔ)空間。而使用未能被適當(dāng)規(guī)范化的關(guān)系帶來的問題詳見第 3 小節(jié)。

2. 規(guī)范化對(duì)數(shù)據(jù)庫設(shè)計(jì)的支持

規(guī)范化是一種能夠應(yīng)用于數(shù)據(jù)庫設(shè)計(jì)任何階段的形式化技術(shù)。這里著重強(qiáng)調(diào)規(guī)范化的兩種使用方法。方法 1 將規(guī)范化視為一種自下而上的獨(dú)立的數(shù)據(jù)庫設(shè)計(jì)技術(shù)。方法 2 則將規(guī)范化作為一種確認(rèn)技術(shù)使用:用規(guī)范化技術(shù)檢驗(yàn)關(guān)系的結(jié)構(gòu),而這些關(guān)系的建立可能采用自上而下的方法,比如 ER 建模。不管使用哪一種方法,目標(biāo)都是一致的,即建立一組設(shè)計(jì)良好(well-designed)的關(guān)系以滿足企業(yè)的數(shù)據(jù)需求。

如何使用規(guī)范化技術(shù)支持?jǐn)?shù)據(jù)庫設(shè)計(jì)

上圖給出了一些能夠用來進(jìn)行數(shù)據(jù)庫設(shè)計(jì)的數(shù)據(jù)源示例。盡管用戶的需求規(guī)格說明書是首選的數(shù)據(jù)源,但是僅基于直接從其他數(shù)據(jù)源獲得的信息進(jìn)行數(shù)據(jù)庫設(shè)計(jì)也是可能的,這些數(shù)據(jù)源包括表單和報(bào)表。上圖還說明對(duì)同一個(gè)數(shù)據(jù)源兩種方法均適用。然而盡管理論上如此,實(shí)際操作時(shí)究竟采用哪一種方法還要取決于數(shù)據(jù)源反映出的數(shù)據(jù)庫的大小、范圍以及復(fù)雜度,同時(shí)還取決于數(shù)據(jù)庫設(shè)計(jì)者的偏好及其專長(zhǎng)。是否將規(guī)范化作為一種自上而下的獨(dú)立的數(shù)據(jù)庫設(shè)計(jì)技術(shù)(即方法 1)使用,常常受限于數(shù)據(jù)庫設(shè)計(jì)者對(duì)設(shè)計(jì)細(xì)節(jié)的掌握程度。然而,當(dāng)我們將規(guī)范化作為一種確認(rèn)技術(shù)(即方法 2)使用時(shí),就沒有了這種限制。因?yàn)樵谶@種使用方法中,數(shù)據(jù)庫設(shè)計(jì)者在任何時(shí)刻都能專注于數(shù)據(jù)庫的一部分,例如一個(gè)單一的關(guān)系,因此,不管數(shù)據(jù)庫的大小或者復(fù)雜度如何,規(guī)范化都能發(fā)揮效能。

3. 數(shù)據(jù)冗余與更新異常

如上所述,關(guān)系數(shù)據(jù)庫設(shè)計(jì)的一個(gè)主要目標(biāo)就是將屬性組合成關(guān)系時(shí)力求最少的數(shù)據(jù)冗余。如果能夠達(dá)到這個(gè)目標(biāo),就可能為數(shù)據(jù)庫帶來以下好處:

  • 能用最少的操作完成對(duì)數(shù)據(jù)庫中存儲(chǔ)數(shù)據(jù)的更新,由此可以降低數(shù)據(jù)庫中出現(xiàn)數(shù)據(jù)不一致的概率。

  • 減少存儲(chǔ)基本關(guān)系所需的文件存儲(chǔ)空間,因而將成本降低至最低。

當(dāng)然,關(guān)系數(shù)據(jù)庫(的運(yùn)行)也依賴于一定的數(shù)據(jù)冗余的存在。這種冗余一般是以主關(guān)鍵字(或者候選關(guān)鍵字)的多個(gè)副本的形式出現(xiàn),這些副本在與之相關(guān)聯(lián)的關(guān)系(即主關(guān)鍵字或候選關(guān)鍵字所述的關(guān)系)中,做為外部關(guān)鍵字出現(xiàn),用以表示數(shù)據(jù)之間的聯(lián)系。

舉例說明:

關(guān)系 StaffBranch 是關(guān)系 Staff 和 關(guān)系 Branch 的另一種表達(dá)方式,這些關(guān)系的結(jié)構(gòu)如下所示:

Staff           (staffNo, sName, position, salary, branchNo)
Branch          (branchNo, bAddress)
StaffBranch     (staffNo, sName, position, salary, branchNo, bAddress)

注意,每個(gè)關(guān)系的主關(guān)鍵字都有下劃線。

在關(guān)系 StaffBranch 中存在冗余數(shù)據(jù):同一個(gè)分公司的信息在每一個(gè)屬于該分公司的員工信息里反復(fù)出現(xiàn)。相反,在關(guān)系 Branch 中,每個(gè)分公司的信息只出現(xiàn)了一次,而且在關(guān)系 Staff 中只有分公司的編號(hào)(branchNo)這一屬性的值重復(fù)出現(xiàn),這是為了能夠表示出每一個(gè)員工都?xì)w屬于哪一個(gè)分公司。存在冗余數(shù)據(jù)的關(guān)系可能存在一些問題——更新異常,更新異常又可分為插入異常、刪除異常和修改異常。關(guān)系 Staff 關(guān)系 Branch 和關(guān)系 StaffBranch表如下所示。

Staff

staffNo sName position salary branchNo
SL21 John White Manager 30000 B005
SG37 Ann Beech Assistant 12000 B003
SG14 David Ford Supervisor 18000 B003
SA9 Mary Howe Assistant 9000 B007
SG5 Susan Brand Manager 24000 B003
SL41 Julie Lee Assistant 9000 B005

Branch:

branchNo bAddress
B003 163 Main St, Glasgow
B007 16 Argyll St, Aberdeen
B005 22 Deer Rd, London

StaffBranch:

staffNo sName position salary branchNo bAddress
SL21 John White Manager 30000 B005 22 Deer Rd, London
SG37 Ann Beech Assistant 12000 B003 163 Main St, Glasgow
SG14 David Ford Supervisor 18000 B003 163 Main St, Glasgow
SA9 Mary Howe Assistant 9000 B007 16 Argyll St, Aberdeen
SG5 Susan Brand Manager 24000 B003 163 Main St, Glasgow
SL41 Julie Lee Assistant 9000 B005 22 Deer Rd, London

3.1 插入異常

插入異常主要有兩類,我們用上表中的關(guān)系 StaffBranch 來解釋這兩類異常。

  • 在關(guān)系 StaffBranch 中插入一位新員工的信息時(shí),這些信息中必須包括該員工將被分配到分公司的信息。比如,在插入某一被分配到編號(hào)為 B007 的分公司工作的員工信息時(shí),我們必須正確輸入分公司 B007 的所有信息,由此確保這些數(shù)據(jù)與關(guān)系 StaffBranch 已有的關(guān)于分公司 B007 的元組中的信息一致。而 Staff 和 Branch 關(guān)系則不存在這種潛在的不一致性,因?yàn)樵陉P(guān)系 Staff 中,秩序?yàn)槊總€(gè)員工錄入相應(yīng)的分公司編號(hào)就可以了,而在關(guān)系 Branch 中,編號(hào)為 B007 的分公司的信息是作為一個(gè)單獨(dú)的元組存儲(chǔ)在數(shù)據(jù)庫中的。

  • 在向關(guān)系 StaffBranch 中插入一個(gè)新的分公司的信息時(shí),由于該分公司目前可能還沒有給員工,因此有必要在錄入與員工相關(guān)的信息時(shí)將其設(shè)為 NULL,如將 staffNo 賦值為 NULL。但是 staffNo 是關(guān)系 StaffBranch 的主關(guān)鍵字,若試圖為 staffNo 錄入 NULL 值,則會(huì)違反實(shí)體完整性約束,這樣做是不允許的,我們也因此無法向關(guān)系 StaffBranch 中插入一個(gè) staffNo 為 NULL的一個(gè)新的分公司的元組。Staff 和 Branch 的關(guān)系設(shè)計(jì)則避免了這類問題的出現(xiàn),因?yàn)榉止镜男畔⒃陉P(guān)系 Branch 中單獨(dú)錄入,與員工信息分離,而員工被分配到哪個(gè)分公司工作的信息則會(huì)在以后的時(shí)間再錄入關(guān)系 Staff 中。

3.2 刪除異常

從關(guān)系 StaffBranch 中刪除一個(gè)元組時(shí),若該元組表示某分公司最后一名員工,則刪除元組之后,該分公司的信息也從數(shù)據(jù)庫中丟失了。例如,如果從關(guān)系 StaffBranch 中刪除員工編號(hào)為 SA9 的元組,則編號(hào)為 B007 的分公司的信息也將從數(shù)據(jù)庫中消失。同樣的,Staff 和 Branch 的分開設(shè)計(jì)避免了這個(gè)問題。

3.3 修改異常

如果我們想要修改關(guān)系 StaffBranch 中某分公司的某個(gè)屬性值,比如修改分公司 B003 的地址,那么我們必需更新所有 B003 的員工的元組。若如此修改操作未能在關(guān)系 StaffBranch 中所有相關(guān)的元組上執(zhí)行,數(shù)據(jù)庫則會(huì)產(chǎn)生不一致:同屬分公司 B003 的員工,其元組在分公司地址這一屬性上的取值可能會(huì)有不同。

上面的示例說明了 Staff 和 Branch 的分開設(shè)計(jì)比 StaffBranch 的設(shè)計(jì)具有更令人滿意的特性。也就是說,當(dāng)關(guān)系 StaffBranch 發(fā)生更新異常時(shí),我們可以通過將其分解為 Staff 和 Branch 兩個(gè)關(guān)系來避免這些異常。當(dāng)把較大的關(guān)系分解成較小的關(guān)系時(shí),有兩個(gè)很重要的特性:

  • 無損連接(lossless-join):該特性確保了緣關(guān)系的任意實(shí)例信息能通過較小關(guān)系的對(duì)應(yīng)實(shí)例確定出來。

  • 依賴保持(dependency preservation):該特性確保了只需簡(jiǎn)單的在較小的關(guān)系上支持某些約束,就可以繼續(xù)支持在原關(guān)系上存在的約束。也就是說,我們不必對(duì)較小的關(guān)系執(zhí)行連接操作就可以檢驗(yàn)他們是否違反了原關(guān)系上的約束。

4. 函數(shù)依賴

與規(guī)范化相關(guān)的一個(gè)重要概念就是 函數(shù)依賴,函數(shù)依賴描述了屬性之間的聯(lián)系(Maier,1983)。

4.1 函數(shù)依賴的特征

為了討論函數(shù)依賴,假設(shè)有某一關(guān)系模式,該關(guān)系模式具有屬性(A,B,C, ... ,Z),我們用一個(gè) 全域關(guān)系(universal relation)R = (A,B,C,...,Z)來描述數(shù)據(jù)庫。該假設(shè)意味著每個(gè)數(shù)據(jù)庫中的屬性都有一個(gè)唯一的名字。

函數(shù)依賴(functional dependency):描述一個(gè)關(guān)系中屬性之間的聯(lián)系。例如,假設(shè) A 和 B 均為關(guān)系 R 的屬性,若 A 的每個(gè)值都和 B 中一個(gè)唯一的值相對(duì)應(yīng),則稱 B 函數(shù)依賴于 A,記為 A → B(A,B可能由一個(gè)或多個(gè)屬性組成)。

函數(shù)依賴是屬性在關(guān)系中的一種語義特性。該語義特性表明了屬性和屬性是如何關(guān)聯(lián)起來的,確定了屬性之間的函數(shù)依賴。當(dāng)存在某一函數(shù)依賴時(shí),這個(gè)以來就被視為屬性之間的一種 約束

考慮某一關(guān)系,它擁有屬性 A、B,其中屬性 B 函數(shù)依賴于屬性 A。假設(shè)知道 A 的值,我們來驗(yàn)證該關(guān)系是否支持這種依賴。結(jié)果我們發(fā)現(xiàn)無論任何時(shí)候,對(duì)于所有元組,若屬性 A 的值等于給定值,則該元組的屬性 B 的值都是唯一的。因此,當(dāng)兩個(gè)元組的屬性 A 的值相同時(shí),其屬性 B 的值也是相同的。反之則不然,對(duì)于一個(gè)給定的 B 的值,可能對(duì)應(yīng)著幾個(gè)不同的 A 的值。屬性 A、B 之間這種以來可以用下圖表示。

函數(shù)依賴圖

另外一種描述屬性 A、B 之間的這種聯(lián)系的術(shù)語為 “A 函數(shù)決定 B”。也許一些讀者更喜歡使用后者,因?yàn)樗c屬性之間的函數(shù)依賴的箭頭的方向相同,顯得更自然一些。

決定方:位于函數(shù)依賴箭頭左邊的屬性或?qū)傩越M。

當(dāng)存在函數(shù)依賴時(shí),位于箭頭左邊的屬性或?qū)傩越M稱為 決定方(determinant) 。例如,上圖中,A 是 B 的決定方。

在確定一個(gè)關(guān)系中屬性間的函數(shù)依賴時(shí),必須明確它是僅當(dāng)屬性取某一特定值時(shí)成立,還是該屬性取值集中任意值時(shí)均成立,區(qū)分清楚這一點(diǎn)很重要。換句話說,函數(shù)依賴是關(guān)系模式(內(nèi)涵)的性質(zhì),而不是模式的某個(gè)實(shí)例(外延)的性質(zhì)。

另一個(gè)規(guī)范化時(shí)有用的函數(shù)依賴的性質(zhì)是:決定方應(yīng)該具有最少的屬性,這些屬性是保證右邊的屬性函數(shù)依賴于它所必不可少的。我們稱其為 完全函數(shù)依賴。

完全函數(shù)依賴(full functional dependency):假設(shè) A 和 B 是某一關(guān)系的屬性(組),若 B 函數(shù)依賴于 A,但不函數(shù)依賴于 A 的任一真子集,則稱 B 完全函數(shù)依賴于 A。

對(duì)于函數(shù)依賴 A → B,如果去掉 A 中的任一屬性都使得該依賴不再成立,那么 A → B 就是完全函數(shù)依賴。如果去掉 A 中的某些屬性,依賴仍然成立,那么函數(shù)依賴 A → B 就是 部分函數(shù)依賴

概括而言,規(guī)范化時(shí)要用到的函數(shù)依賴具有下列性質(zhì):

  • 函數(shù)依賴左邊的屬性(組)(即決定方)與右邊的屬性(組)是一對(duì)一的聯(lián)系(注意,若反過來看,也就是右邊與左邊的屬性(組)之間則既可能為一對(duì)一的聯(lián)系,也可能為一對(duì)多的聯(lián)系)。
  • 恒成立。
  • 決定方具有最少的、足以支持與右邊的屬性(組)之間依賴關(guān)系的屬性,即右邊的屬性(組)完全依賴于左邊的屬性(組)。

至此,我們已經(jīng)討論了在規(guī)范化時(shí)所關(guān)心的一些函數(shù)依賴,但是還有必要了解一種函數(shù)依賴,即 傳遞依賴(transitive dependency)。因?yàn)殛P(guān)系中若存在傳遞依賴,就有可能引起更新異常。本節(jié)只簡(jiǎn)單介紹傳遞依賴,目的是在需要時(shí)我們能夠識(shí)別出他們。

傳遞依賴:假設(shè) A、B、C 是某一關(guān)系的屬性,若 A → B,B → C,則稱 C 通過 B 傳遞依賴于 A(假設(shè) A 并不函數(shù)依賴于 B 或 C)。

4.2 識(shí)別函數(shù)依賴

如果我們能夠完全理解每一個(gè)屬性的意義以及這些屬性之間的聯(lián)系,那么確定屬性之間所有的函數(shù)依賴應(yīng)該非常簡(jiǎn)單。這類信息應(yīng)由企業(yè)提供,可能是通過與用戶討論形成,同時(shí)(或者)也可能是以文檔的形式出現(xiàn),比如用戶需求規(guī)格說明書。但是,如果與用戶無法溝通,并且(或者)文檔并不完備,那么數(shù)據(jù)庫設(shè)計(jì)人員就有必要基于該數(shù)據(jù)庫應(yīng)用的領(lǐng)域,利用自己的常識(shí)或經(jīng)驗(yàn)來補(bǔ)充那些缺失的信息。

4.3 利用函數(shù)依賴確定主關(guān)鍵字

確定關(guān)系函數(shù)依賴集的主要目的是確定該關(guān)系必須滿足的完整性約束集。首先要考慮辨別的一種重要的完整性約束是候選關(guān)鍵字,候選關(guān)鍵字中的一個(gè)將被選作關(guān)系的主關(guān)鍵字。

5. 規(guī)范化過程

規(guī)范化是一種基于關(guān)系的主關(guān)鍵字(或者候選關(guān)鍵字)和函數(shù)依賴對(duì)關(guān)系進(jìn)行分析的形式化技術(shù)(Codd,1972b)。規(guī)范化技術(shù)涉及一系列的規(guī)則,這些規(guī)則能夠用來對(duì)關(guān)系進(jìn)行單獨(dú)測(cè)試以保證數(shù)據(jù)庫可以被規(guī)范化到任意程度。當(dāng)某種規(guī)范化的要求未能得到滿足時(shí),就將違反需求的關(guān)系分解為多個(gè)關(guān)系,直至分解后的每一個(gè)關(guān)系都能滿足規(guī)范化的要求為止。

最早提出的三個(gè)范式為第一范式(1NF)、第二范式(2NF)和第三范式(3NF)。后來,R.Boyce 和 E.F.Codd 又提出了一種增強(qiáng)的第三范式,稱為 Boyce-Codd 范式(BCNF)(Codd,1974)。除了第一范式,所有這些范式都是基于關(guān)系的屬性之間的函數(shù)依賴的(Maier,1983)。隨后還提出了比 BCNF 更高層的范式——第四范式(4NF)和第五范式(5NF)(Fagin,1977, 1979)。但是,需要用到第四范式、第五范式的情況相當(dāng)少。本篇中將只講述前三種范式,對(duì) BCNF、4NF 和 5NF 的討論則留到下一章進(jìn)行。

規(guī)范化的過程包括一系列步驟,每一步都對(duì)應(yīng)著某種具有已知性質(zhì)的特定范式。隨著規(guī)范化的進(jìn)行,關(guān)系的個(gè)數(shù)逐漸增多,關(guān)系的形式也逐漸受限(結(jié)構(gòu)越來越好),也就越來越不容易出現(xiàn)更新異常。對(duì)于關(guān)系數(shù)據(jù)模型,應(yīng)該認(rèn)識(shí)到在建立關(guān)系時(shí)只有滿足第一范式(1NF)的要求是必須的,后面的其他范式都是可選的,這一點(diǎn)很重要。但是為了避免出現(xiàn)前面討論過的更新異常的情況,通常建議將規(guī)范化至少進(jìn)行到第三范式(3NF)。從第一范式到第五范式是是逐步遞進(jìn)的,第二范式是在滿足第一范式的基礎(chǔ)上增加條件形成的,以此類推。

下圖為規(guī)范化過程的縱覽圖,途中突出顯示了規(guī)范化過程中每一個(gè)步驟的主要操作。

規(guī)范化過程

這里我們將規(guī)范化視為一種自下而上的技術(shù),主要講述如何利用這種技術(shù)從案例表單中抽取屬性信息,并先將其轉(zhuǎn)化為非范式(Unnormalized Form,UNF)表格的形式,然后將其逐漸分解以滿足每一種范式的要求,分解一直進(jìn)行到原案例表中的屬性都被分解為若干滿足 3NF 要求的關(guān)系為止。盡管這里使用的例子都是從某一范式規(guī)范化到更高一級(jí)的范式,但是,對(duì)于其他的例子來說并不一定必須這么做。在解決某些特殊問題時(shí),我們可以將 1NF 的關(guān)系轉(zhuǎn)換為 2NF 的關(guān)系,或者在某些情況下,直接將其轉(zhuǎn)化為 3NF 的關(guān)系。

為了簡(jiǎn)化對(duì)規(guī)范化的講述,我們假設(shè)在所用案例中,每一個(gè)關(guān)系都有一個(gè)函數(shù)依賴集,每一個(gè)關(guān)系都已被指派了一個(gè)主關(guān)鍵字。也就是說,在規(guī)范化的過程開始之前,充分、完全地理解屬性的意義及其之間的聯(lián)系是必要的。這些信息是進(jìn)行規(guī)范化的基礎(chǔ),我們將利用這些信息來驗(yàn)證一個(gè)關(guān)系是否已經(jīng)滿足了指定范式的要求。

6. 第一范式(1NF)

非范式(UNF):包含一個(gè)或多個(gè)重復(fù)組的表。
第一范式(1NF):屬于第一范式的關(guān)系,其每一行和每一列相交的位置有且僅有一個(gè)值。

我們開始進(jìn)行規(guī)范化之前,首先要將數(shù)據(jù)從數(shù)據(jù)源(例如標(biāo)準(zhǔn)的數(shù)據(jù)輸入表單)轉(zhuǎn)換為包含行和列的表格形式。這種格式的表是非范式的,因而被視為 非規(guī)范化的表(unnormalized table)。為了將非規(guī)范化的表轉(zhuǎn)化為第一范式,我們需要確定并刪除表中的重復(fù)組。一個(gè)重復(fù)組可以是一個(gè)屬性或一組屬性,它對(duì)應(yīng)表的某個(gè)(些)關(guān)鍵屬性的一個(gè)實(shí)例可能出現(xiàn)多個(gè)值。注意,這里所說的 “關(guān)鍵屬性” 是指非規(guī)范化的表中那些可以唯一標(biāo)識(shí)每一行的屬性(組)。從非規(guī)范化的表中消除重復(fù)組的常用方法有兩種:

  1. 在含有重復(fù)數(shù)據(jù)的那些行的空白列上輸入合適的數(shù)據(jù),也就是在需要填充的位置復(fù)制非重復(fù)數(shù)據(jù)。這種方法通常被看做是對(duì)表的平板化(flattening)處理。

  2. 將重復(fù)數(shù)據(jù)單獨(dú)移到一個(gè)新的關(guān)系中,同時(shí)也將原來關(guān)系中的關(guān)鍵屬性(組)復(fù)制到這個(gè)新的關(guān)系中。有時(shí)候,非規(guī)范化的表可能包含多個(gè)重復(fù)組,或者在重復(fù)組里又有重復(fù)組。在這些情況下,重復(fù)使用這一方法直到不再存在重復(fù)組位置。若結(jié)果關(guān)系均不含重復(fù)組,則他們都是 1NF 的。

這兩種方法得到的結(jié)果關(guān)系都是 1NF 的關(guān)系,在行、列交叉處都只包含原子(或單一)值。盡管兩種方法都是正確的,然而方法 1 在對(duì)原 UNF 的表進(jìn)行平板化的過程中也引入了較多的冗余;方法 2 則創(chuàng)建了兩個(gè)或更多的關(guān)系,這些關(guān)系的冗余度都低于原 UNF 的表的冗余度。換句話說,在對(duì)原 UNF 的表的規(guī)范化過程中,方法 2 比方法 1 做的工作更多。但是,不管從哪一種方法開始,原 UNF 的表終將被規(guī)范化為一組相同的 3NF 的關(guān)系。

7. 第二范式(2NF)

第二范式基于完全函數(shù)依賴的概念,第二范式適用于具有合成關(guān)鍵字的關(guān)系,即主關(guān)鍵字有兩個(gè)或兩個(gè)以上的屬性構(gòu)成。主關(guān)鍵字僅包含一個(gè)屬性的關(guān)系已經(jīng)至少是 2NF 的。不是 2NF 的關(guān)系可能會(huì)出現(xiàn)前面討論過的更新異常。

第二范式 (2NF):滿足第一范式的要求并且每個(gè)非主關(guān)鍵字屬性都完全函數(shù)依賴與主關(guān)鍵字的關(guān)系。

將 1NF 的關(guān)系規(guī)范化為 2NF 關(guān)系需要消除部分依賴。如果存在部分依賴,就要將部分依賴的屬性從原關(guān)系移出,移到一個(gè)新的關(guān)系中去,同時(shí)將這些屬性的決定方也復(fù)制到新的關(guān)系中。

8. 第三范式(3NF)

盡管 2NF 的關(guān)系比 1NF 關(guān)系的數(shù)據(jù)冗余度低,但是仍然存在更新異常問題。此時(shí)的更新異常是由依賴傳遞引起的,我們需要消除這種依賴,繼續(xù)將關(guān)系規(guī)范化到第三范式。

第三范式(3NF):滿足第一范式和第二范式的要求并且所有非主關(guān)鍵字屬性都不傳遞依賴于主關(guān)鍵字的關(guān)系。

將 2NF 的關(guān)系規(guī)范化為 3NF 需要消除傳遞依賴。如果存在傳遞依賴,就將傳遞依賴的屬性(組)移到一個(gè)新的關(guān)系中,并將這些屬性的決定方也復(fù)制到該關(guān)系中。

9. 2NF 和 3NF 的一般化定義

在前兩節(jié)的 2NF 和 3NF 的定義中,不允許存在對(duì)主關(guān)鍵字的部分依賴和傳遞依賴,以此避免出現(xiàn)前述的更新異?,F(xiàn)象。然而,這些定義并沒有考慮關(guān)系中的其他候選關(guān)鍵字(如果存在不止一個(gè)候選關(guān)鍵字)。下面將在考慮關(guān)系的所有候選關(guān)鍵字的基礎(chǔ)上,給出 2NF 和 3NF 的更一般化定義。注意,考慮關(guān)系的候選關(guān)鍵字并不會(huì)影響 1NF 的定義,因?yàn)?1NF 與關(guān)鍵字和函數(shù)依賴無關(guān)。在更一般化的定義中,我們規(guī)定:屬于任何一個(gè)候選關(guān)鍵字的屬性都叫做主屬性(candidate-key attribute);提到部分依賴、完全依賴和傳遞依賴時(shí)不僅僅是基于主關(guān)鍵字,而是基于所有的候選關(guān)鍵字。

第二范式(2NF):滿足第一范式的要求并且每個(gè)非主屬性都完全函數(shù)依賴于任何一個(gè)候選關(guān)鍵字的關(guān)系。

第三范式(3NF):滿足第一范式和第二范式的要求并且沒有一個(gè)非主屬性傳遞依賴于任何一個(gè)候選關(guān)鍵字。

在使用 2NF 和 3NF 的一般化定義時(shí),必須注意的是所有候選關(guān)鍵字上的部分依賴和傳遞依賴,而不只是主關(guān)鍵字上的。這使得規(guī)范化過程變得更加復(fù)雜,但一般化定義能為關(guān)系增加附加約束,從而有可能發(fā)現(xiàn)關(guān)系中隱藏的、被遺漏的冗余。

在進(jìn)行規(guī)范化時(shí),是僅簡(jiǎn)單的分析主關(guān)鍵字上的依賴,還是使用一般化定義進(jìn)行規(guī)范化,這需要權(quán)衡。前者使得規(guī)范化過程簡(jiǎn)單,并且可以發(fā)現(xiàn)關(guān)系中存在的大多數(shù)問題和明顯的數(shù)據(jù)冗余;后者則有更多的機(jī)會(huì)發(fā)現(xiàn)關(guān)系中被遺漏的冗余。實(shí)際上, 常見的情形是,無論使用基于主關(guān)鍵字的定義還是使用 2NF、3NF 的一般化定義,對(duì)關(guān)系進(jìn)行分解的結(jié)果相同。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容