出處:http://blog.csdn.net/lenotang/article/details/3304575
數據規範化
• 僅有好的RDBMS並不足以避免數據冗餘,必須在數據庫的設計中創建好的表結構。表設計後,很可能結構不合理,出現數據重複保存,簡稱數據的冗餘,這對數據的增刪改查帶來很多後患,所以我們需要審覈是否合理,就像施工圖設計後,還需要其他機構進行審覈圖紙是否設計合理一樣。
• 如何審覈呢?需要一些有關數據庫設計的理論指導規則,這些規則業界簡稱數據庫的範式。Dr E.F.codd 最初定義了規範化的三個級別,範式是具有最小冗餘的表結構。這些範式是:
– 第一範式(1st NF -First Normal Fromate)
– 第二範式(2nd NF-Second Normal Fromate)
– 第三範式(3rd NF- Third Normal Fromate)
• 如果每列都是不可再分的最小數據單元(也稱爲最小的原子單元),則滿足第一範式(1NF)。第一範式的目標是確保每列的原子性。
• 如果一個關係滿足1NF,並且除了主鍵以外的其他列,都依賴於該主鍵,則滿足第二範式(2NF)。第二範式要求每個表只描述一件事情,確保表中的每列,都和主鍵相關。
• 如果一個關係滿足2NF,並且除了主鍵以外的其他列都不傳遞依賴於主鍵列,則滿足第三範式(3NF)。第三範式確保每列都和主鍵列直接相關,而不是間接相關。
下面我們來看個形象的例子吧!假設某建築公司要設計一個數據庫。公司的業務規則概括說明如下:
• 公司承擔多個工程項目,每一項工程有:工程號、工程名稱、施工人員等
• 公司有多名職工,每一名職工有:職工號、姓名、性別、職務(工程師、技術員)等
• 公司按照工時和小時工資率支付工資,小時工資率由職工的職務決定(例如,技術員的小時工資率與工程師不同)
• 公司定期制定一個工資報表,如圖-1所示
工程號 |
工程名稱 |
職工號 |
姓名 |
職務 |
小時工資率 |
工時 |
實發工資 |
A1 |
花園大廈 |
1001 |
齊光明 |
工程師 |
65 |
13 |
845.00 |
1002 |
李思岐 |
技術員 |
60 |
16 |
960.00 | ||
1004 |
葛宇宏 |
律師 |
60 |
19 |
1140.00 | ||
|
|
|
小計 |
|
|
|
2945.00 |
A2 |
立交橋 |
1001 |
齊光明 |
工程師 |
65 |
15 |
975.00 |
1003 |
鞠明亮 |
工人 |
55 |
17 |
935.00 | ||
|
|
|
小計 |
|
|
|
1910.00 |
A3 |
臨江飯店 |
1002 |
李思岐 |
技術員 |
60 |
18 |
1080.00 |
1004 |
葛宇洪 |
律師 |
60 |
14 |
840.00 | ||
|
|
|
小計 |
|
|
|
1920.00 |
圖-1 某公司打印的工資報表
工程號 |
工程名稱 |
職工號 |
姓名 |
職務 |
小時工資率 |
工時 |
A1 |
花園大廈 |
1001 |
齊光明 |
工程師 |
65 |
13 |
A1 |
花園大廈 |
1002 |
李思岐 |
技術員 |
60 |
16 |
A1 |
花園大廈 |
1004 |
葛宇洪 |
律師 |
60 |
19 |
A2 |
立交橋 |
1001 |
齊光明 |
工程師 |
65 |
15 |
A2 |
立交橋 |
1003 |
鞠明亮 |
工人 |
55 |
17 |
A3 |
臨江飯店 |
1002 |
李思岐 |
技術員 |
60 |
18 |
A3 |
臨江飯店 |
1004 |
葛宇洪 |
律師 |
60 |
14 |
圖-2 某公司的項目工時表
大家都看到,上面這樣設計的表會有很多問題:
1.表中包含大量的冗餘,可能會導致數據異常:
• 更新異常
例如,修改職工號=1001的職務,則必須修改所有職工號=1001的行
• 添加異常
若要增加一個新的職工時,首先必須給這名職工分配一個工程。或者爲了添加一名新職工的數據,先給這名職工分配一個虛擬的工程。(因爲主關鍵字不能爲空)
• 刪除異常
例如,1001號職工要辭職,則必須刪除所有職工號=1001的數據行。這樣的刪除操作,很可能丟失了其它有用的數據
2.採用這種方法設計表的結構,雖然很容易產生工資報表,但是每當一名職工分配一個工程時,都要重複輸入大量的數據。這種重複的輸入操作,很可能導致數據的不一致性。
我們用第二範式規範一下:
我們再用第三範式規範一下,是不是明晰了很多?!
規範化和性能的關係
• 爲滿足某種商業目標,數據庫性能比規範化數據庫更重要
– 通過在給定的表中添加額外的字段,以大量減少需要從中搜索信息所需的時間
– 通過在給定的表中插入計算列(如成績總分),以方便查詢
• 進行規範化的同時,還需要綜合考慮數據庫的性能。數據庫的三大範式和數據庫的性能有時是矛盾的。
打個比方:大家都知道,環境保護非常重要,西方總是拿環保問題和中國刁難,說中國爲了發展不顧環境保護、生態自然等。可中國目前的經濟實力不夠強大,如果人都吃不飽,空談環保還有什麼用呢?所以我們只能是在保持地區經濟發展的前提下,儘量注重環保問題。這就是一種折中處理問題的典型。本例同樣如此:爲了滿足三大範式,我們在規範化表格時就會拆分出越來越明細的表格。但客戶喜歡綜合的信息,爲了滿足客戶,我們又需要把這些表通過連接查詢還原爲客戶喜歡的綜合數據。這和從一張表中讀出數據相比,大大影響了數據庫的查詢性能。所以有時爲了性能,需要做適當折中,適當犧牲規範化的要求,來提高數據庫的性能。再如:在成績表中添加一列-“成績總分”,屬於數據冗餘,因爲總分在查詢時可由各門成績求出來。但頻繁查詢成績總分,並希望保存下來,所以有時表中就乾脆添加總分這一列。