資料庫正規化介紹(1NF, 2NF, 3NF)


為什麼要做資料庫正規化(Normalization)?

最大的優點是能夠防止更新異常、減少資料庫中的重複資料,提高資料庫的性能、可維護性和資料一致性。

優點:
  • 減少資料冗餘
  • 提高資料一致性
  • 提高資料庫性能
  • 更方便維護資料
  • 更方便查詢
  • 更容易擴充
缺點
  • 資料表數量增加、增加更多關聯
  • 需要更多 Join 語法,有時可能降低效能
  • 不適合全部場景
資料庫正規化是針對關聯式資料庫(Relational Database, RDB)的規則,對於 NoSQL(Not only SQL) 而言,大多會使用 Json 來儲存多筆資料,直接違反第一正規化。且 NoSQL 通常會使用資料冗餘來換取更好的效能和擴充,與關聯式資料庫目的較為不同,故不適用資料庫正規化。

常見的正規化種類

資料庫正規化常見的有以下幾種,由上往下分別是:
  • 第一正規化
  • 第二正規化
  • 第三正規化
  • Boyce–Codd 正規化(本文未介紹)

第一正規化(First Normal Form, 1NF)

規則:
  • 每個資料表都必須要有一個主鍵(Primary key)
  • 每一欄(column)都必須包含不可分割的一個值(Atomic Value)。錯誤範例: 「產品名稱」欄位中有多個內容: 蘋果,橘子
  • 每一欄(column)都應該要有一個唯一的名稱或用途。錯誤範例: 有「產品名稱1」和「產品名稱2」兩個欄位
錯誤範例:
客戶姓名 客戶電話 產品名稱 單價 數量 總金額
大頭 0912345678 蘋果,橘子 14,15 6,10 234
小明 0923456789 草莓(公斤) 90 5 450
上面的資料主要的問題是「產品」、「單價」、「數量」欄位可能有多筆資料,在程式的處理非常不方便。 且在單價和數量應該要是數值型態,為了要儲存多個內容要轉換為文字,在內容輸入和後續處理都會造成麻煩。
另外目前資料並沒有「主鍵」故我們加上「訂單編號」,內容直接使用流水號。

做完第一正規化後結果:
訂單編號 客戶姓名 客戶電話 產品名稱 單價 數量 總金額
1 大頭 0912345678 蘋果 14 6 84
2 大頭 0912345678 橘子 15 10 150
3 小明 0923456789 草莓(公斤) 90 5 450
雖然目前多了重複的資料(客戶姓名、客戶電話),但是我們已經修正資料格式的問題,未來不論是在新增(數字欄位不會再輸入文字)、修改、刪除(能夠直接刪除其中一項產生購買紀錄)、查詢上都能夠非常容易。

第二正規化(Second Normal Form, 2NF)

規則:
  • 符合第一正規化
  • 消除部份相依,除了主鍵以外,每一欄(column)資料都必須要依賴主鍵
上面的表目前的問題為無法只新增客戶資料,且客戶姓名和客戶電話會重複輸入。若大頭改了電話,那就需要檢查每一筆資料。若有一欄沒有修改到,導致資料不一致,就會無法確認哪筆資料是錯誤的。

我們可以將客戶資料和訂單紀錄拆分,不紀錄客戶實際資料,而是只儲存客戶資料的主鍵。且產品單價也是依賴於產品名稱,所以也會建立產品資料表

客戶資料表

客戶編號 客戶姓名 客戶電話
1 大頭 0912345678
2 小明 0923456789

訂單資料表

訂單編號 客戶編號 產品編號 數量 總金額
1 1 1 6 84
2 1 2 10 150
3 2 3 5 450

產品資料表

產品編號 產品名稱 單價
1 蘋果 14
2 橘子 15
3 草莓(公斤) 90

第三正規化(Third Normal Form, 3NF)

規則:
  • 符合第二正規化
  • 消除遞移相依 (Transitive Dependency),確保每個非鍵值欄位都是獨立的
什麼叫做「遞移相依」?就是非主鍵欄位有依賴主鍵以外的欄位。以「訂單資料表」來說,「總金額」依賴「產品編號」(找到單價)、「數量」,才能計算出「總金額」,這就叫做遞移相依。
要消除遞移相依的原因就是若今天修改了產品資料表的「單價」,就需要把「總金額」再修改一次,若有沒有修改的部分,就會出現資料不一致的錯誤。解決的方式就是將「總金額」欄位移除。

訂單資料表

訂單編號 客戶編號 產品編號 數量
1 1 1 6
2 1 2 10
3 2 3 5

結語

資料庫正規化能夠帶來許多好處,不過這並不是絕對的。許多系統並不會也不能夠執行到第三正規化,例如資料表拆分後會過於複雜,或是訂單明細資料表一定要保留所有詳細資料等等。
但是了解資料庫正規化後能夠提供給我們一個設計的準則,讓我們在日後系統維護上更佳的容易。

參考資料:
Wiki - Database normalization
A Simple Guide to Five Normal Forms in Relational Database Theory

留言

  1. 太感谢了,之前一直不理解1nf 2nf 3nf的关系,现在清晰一点了

    回覆刪除

張貼留言

如果有任何問題、建議、想說的話或文章題目推薦,都歡迎留言或來信: a@ruyut.com