摘要:規范化是減少數據冗余、設計合理的數據庫的重要手段,是數據庫課程的重點。由于涉及到關系數學理論,僅做理論講解,很難使學生理解,尤其是高職層次的學生。本文通過一個關系模式不斷分解、規范化的實例,采用逐步深入的方法解決數據庫設計中存在的問題,使學生既掌握數據庫設計的技能,也加深對函數依賴、規范化理論的理解。
關鍵詞:關系數據庫;規范化;反規范化;范式;函數依賴
中圖分類號:G64文獻標識碼:A文章編號:1009-3044(2008)24-1113-02
Example Analysis of Normalization and De-normalization of Relational Modal
CAO Chun-hua
(Faculty of Information Engineering, Guangdong Lingnan College, Guangdong 510663, China)
Abstract: Normalization is an important means of reducing data redundancy and designing rational database. It is the key point of the database course. As the relational mathematics theory is concerned, it is difficult for students, especially those in the higher vocational schools to understand if the theory is explained simply. This paper solves step by step the problems of database designing by an example of continuous dissolution and normalization of a relational modal. It enables the students to possess the knowledge of designing database and deepen their understanding of functional dependency and normalization theory.
Key words: relational database; normalization; de-normalization; normal form; functional dependency
1 引入案例
為《在線書店(JSP開發的Web應用)》建立了一個數據庫,為了描述所有客戶的訂單信息,建立關系模式R(OId,Cid,CName,City、Street、ZIP、PId,PName,Price,Qut,Date)。數據如表1所示。
表1 OrderDetails1

模式中的字段(屬性)包括訂單編號(OId)、客戶編號(Cid)、客戶姓名(CName)、客戶城市(City)、客戶街道(Street)、郵政編碼(ZIP)、商品編號(PId)、商品名(PName)、該商品單價(Price)、該商品數量(Qut)、訂單日期(Date)。
簡要地分析這個關系模式,CId、CName等列的數據大量重復出現,可以直觀的看出存在大量的數據冗余。而數據冗余可能導致:
1)插入、更新、刪除異常;2)數據不一致;3)浪費大量的存儲空間。
對于熟練的開發人員可以憑借經驗和常識來設計數據庫模式。然而,對于缺乏經驗的學生而言,可以使用系統方法,如規范化方法來降低冗余,并通過反復的訓練來積累經驗和常識。
2 函數依賴
規范化是在函數依賴范疇內實現關系模式的分離。函數依賴的定義:設R(U)是屬性集U上的關系模式。X,Y是U上的子集(字段或字段組合)。r為R的任一關系(表)。若對r中的任意兩個元組(記錄)u、v,只要有u[X]=v[X],就有u[Y]=v[Y],則稱X函數決定Y,或Y函數依賴與X,記作X->Y,X稱為決定因子。本例中可以看出:(CId)->(CName)。
在R(U)中,如果X->Y,并且對于X的任何一個真子集X’,都有X’->Y不成立,則稱Y完全函數依賴于X。否則稱Y部分函數依賴于X。本例中可以看出:(Qut)完全函數依賴于(OId,PId);(PName)部分函數依賴于(OId,PId)。
在R(U)中,如果X->Y(Y不是X的真子集),且Y->X不成立,Y->Z,則稱Z傳遞函數依賴于X。本例中可以看出:(OId)->(CId),且(CId)->(CName),故(OId)->(CId)->(CName),即(CName)傳遞函數依賴于(OId)。
3 規范化
應用性能直接與數據庫表的設計有關,一個差的表格結構設計阻礙系統的效率,而一個合理的設計奠定了優化數據庫的基礎。規范化幫助簡化表的設計。規范化是一種科學的方法,通過使用某些規則把復雜的表格結構分解為簡單的表格結構。使用這種方法,可以降低表中的冗余、消除不一致、解決更新異常和磁盤空間利用問題,同時保證不存在信息丟失。
3.1 1NF
在一個表中,各字段都是不可再分的原子值,則為第一范式的表,也稱規范化的關系,記為1NF。關系數據庫研究的關系都是規范化的關系。本例中,OrderDetails1表也是1NF的表,從中可以看出1NF存在大量的數據冗余。我們可以通過規范化來減少冗余、解決插入、更新、刪除異常等問題。
3.2 2NF
若R∈1NF,且每個非主屬性都完全依賴于主鍵,則R∈2NF。在OrderDetails表中, Qty完全依賴于主鍵(OId、PId)。而CId、CName、City、Street、ZIP、Date函數依賴于OId,即部分依賴于主鍵(OId,PId)。相似地,PName、Price依賴于主鍵的一部分PId。所以表orders不是一個2NF的表。
將1NF轉化為2NF,將1NF表無損分解為若干各2NF的表。分解方法:采用投影運算,將部分依賴的非主屬性抽取出來與其所依賴的部分主鍵一起構成新表,并組合剩余的屬性與構成原來的表。本例中,抽取CId、CName、City、Street、ZIP、Date再與OId一起構成新表Orders2,;抽取出PName、Price再與PId一起構成新表Products2;組合剩余的屬性OId、PId、Qty構成表OrderDetails2,分別如表2、表3、表4。
分析Orders2,仍然有很大冗余,例如C01、張鏡光重復。且存在如下問題:
1)插入異常。如新注冊的客戶,由于沒有下訂單,而無法插入相應的信息。
2)更新異常。若C01客戶更改地址,必須修改該用戶所有訂單的地址信息,如果漏改一處,則造成數據不一致。
3)刪除異常。若刪除訂單O03,則連同注冊用戶C03、李志平、深圳信息一并刪除,造成數據丟失。
造成數據冗余、及數據插入、更新、刪除異常的原因就是Orders2表中存在傳遞函數依賴:訂單號→客戶編號→(客戶城市、街道)→郵政編碼。
表2 Orders2

表3 Products2

表4 OrderDetails2

表5 Customers3

表6 CSZ3

表7 Orders3

3.3 3NF
若R∈2NF,且每個非主屬性都不傳遞依賴于R的候選鍵,則R∈3NF。
要消除Orders2表中的傳遞函數依賴,分解方式:把傳遞函數依賴的屬性(客戶姓名、客戶城市、街道)抽取出來,并與其所依賴的屬性(客戶標號)一起構成新表Customers3;(郵政編碼)抽取出來,并與其所依賴的屬性(客戶城市、街道)一起構成新表CSZ3;組合剩余的屬性(訂單編號、客戶編號、訂單日期)構成表Orders3。分別如表5、表6、表7。
3.4 BCNF
若R∈2NF,且每個函數依賴X->Y,不論Y是主屬性、還是非主屬性,都有決定因子X包含鍵,則R∈BCNF。3NF不允許有決定因子X不包含鍵,Y是非主屬性的函數依賴,而BCNF則不管Y是主屬性還是非主屬性,其決定因子都必須包含鍵。BCNF是3NF的進一步規范化,即限制條件更嚴格。因此,若R∈BCNF,則必有R∈3NF。
考查表6,也存在種種“問題”,例如,若無街道信息,則一個郵政編碼是那個城市中的郵政編碼就無法存在于數據庫中。表6中的函數依賴集合:F={(City,Street)->ZIP,ZIP->City}。(注意,同一城市的多個街道同一個郵政編碼,所以不存在ZIP->Stree)。(City,Street)和(ZIP,Street)是兩個候選鍵,三個屬性都不是非主屬性,因此CSZ3∈3NF。但是函數依賴ZIP->City的決定因子ZIP不包含碼,所以CSZ3不屬于BCNF。分析該關系模式:
有多個候選鍵,即(City,Street)和(ZIP,Street)。
候選鍵是復合鍵,即每個候選鍵由多個屬性構成。
候選鍵覆蓋,在兩個候選鍵中都有屬性Street。
進一步規范化的分解方式:組合多個候選鍵(City,Street,Street,ZIP),并從中抹去覆蓋的屬性Street,構成新表ZC (ZIP,City);組合不是候選鍵的所有屬性(本例中沒有),并與任一候選鍵(Street,ZIP),組合為新表ZS (ZIP,Street)。
4 反規范化
考慮如下查詢要求:假設銷售的利潤為10%,統計所有訂單的總利潤。從表3(Products2)、表4(OrderDetails2)執行查詢,SQL語句如下:
SELECTSUM((Price * Qty) * 0.10)
FROMOrderDetails2JOINProducts2ONOrderDetails2.PId = Products2.PId由于設計到連接查詢,會很耗時,尤其當兩個表中的記錄數很大時,時間效率很低。如果從表1 OrderDetails1執行查詢,需要一個簡單的SQL語句:
SELECTSUM(Price*Qty)* 0.10FROMOrderDetails1
在一個表格中,有意低引入數據冗余以改進性能稱為反規范化。在涉及到多個表的統計查詢經常發生的數據庫表中,為了提高效率,反規范化是很有必要的。
5 結論
規范化不斷的分解關系模式,使其不斷達到更高的范式,來降低數據冗余,解決插入、修改、刪除異常而引起的數據庫一致性問題,提高了磁盤空間利用率。1NF,2NF,3NF,BCNF的相互關系是BCNF?3NF?2NF?1NF。在函數依賴的范疇內,BCNF達到了最高的規范化程度。通常,范式越高,冗余度越低、磁盤空間利用率越高。但是,范式太高的表,涉及多個表關聯的統計查詢時,效率很低。此時,引用一定的數據冗余是必要的。因此,數據庫設計過程中,我們要根據實際應用需求,權衡考慮空間利用率、數據冗余、數據一致性和時間效率的要求。
參考文獻:
[1] 羅曉沛,侯炳輝.系統分析師教程[M].北京:清華大學出版社,2007.
[2] James R.GrofPaul N.Weinberg.SQL完全參考手冊[M].北京:北京希望電子出版社,2000.
[3] 胡常偉,陳新度.“數據庫原理及應用”課程教學改革初探[J].廣東工業大學學報,2005(5).