2013年7月24日 星期三

正規化(Normalization)

正規化是資料庫設計一個重要的過程。
最早在Codd(1972)提出的正規化形式:第一正規化(first normal form, 1NF)、第二正規化(2NF)、第三正規化(3NF),而Boyce和Codd後來又提出Boyee-Codd正規化(BCNF)。
以上這些是根據功能相依(functional dependent)為基礎,當然還有後來提出的第四正規化(4NF)和第五正規化(5NF),我將在後面再作說明。

快速了解何謂三階正規化:
1NF:去除重複資料

2NF:去除部分相依(partial functional dependency)
3NF:去除遞移相依(transitive dependency)


  • 第一正規化(1NF)
    它不允許欄位存在多值屬性和複合屬性,也就是要求每筆欄位的值組中必須是單值。
    也就是說在這個階段內,如果我們有兩筆相同屬性的資料要紀錄的話,就必須分開來儲存在不同欄位內,如下圖所示,EMPLOYEE有三個屬性,Id是EMPLOYEE的主鍵。
    進行1NF之前
    由上圖可以看出這並不符合1NF,因為Email欄位並不是單值,它包含了兩個Email。正確的做法有以下幾種:
    1.移除Email屬性,另外建立EMP_Email關聯,搭配Id做為關聯的主鍵,此時這個關聯的主鍵是{Id,Email}。在EMP_Email中每一個E-mail只儲存一筆值。這種方法可已將本來不符合1NF的表格分解成兩個符合1NF的關聯。
    2.將原本EMPLOYEE中有多個Email的資料拆成個別值組,如下圖。此時主鍵就變成{Id,Email},但是這種方法會造成資料具有重複計錄的缺點。
    進行1NF之後
    理論上以第一種方法較佳,因為它不會產生資料重複性的問題。但是在實務上多採用的是第二種方法,而且經過後面的正規化步驟還是會解決重複性的問題,變成與第一種方法相同。
  • 第二正規化(2NF)
    滿足1NF,且依據完全功能相依(full functional dependency)的概念為基礎,去除部分功能相依(partial functional dependency),讓資料表內的所有屬性都完全功能相依於主鍵。
    而部分功能相依只會發生在主鍵是由多個屬性值所組成才會發生,假如主鍵只包含一個屬性,則根本不必進行這個測試是否符合2NF。
    進行2NF之前
    由上圖可知,符合1NF但不符合2NF,由於FD2所以非主鍵屬性Name違反了2NF,FD3使得Dname也違反了2NF,而FD2和FD3這兩個功能相依於主鍵{Id,Dnumber},因此違反了2NF。
    當關聯不符合2NF的時候,則可以分解成多個關聯,如下圖分解成FD1、FD2和FD3,使得每個關聯中的非主鍵屬性都能夠完全功能相依於主鍵。
    進行2NF之後
  • 第三正規化(3NF)
    滿足2NF,且依據遞移相依性(transitive dependency)的概念:在關聯中屬性集合C不是任何鍵值,且A→B和B→C,則可以說功能相依A→C是遞移相依。
    如下圖,Id→Dnumber和Dnumber→Dmgr_Id都成立,所以可以說Id→Dmgr_Id具有遞移相依。
    進行3NF之前
    開始進行3NF,分解成如下圖所示的ED1和ED2兩個關聯。
    進行3NF之後