為什麼要做資料庫正規化(Normalization)?
最大的優點是能夠防止更新異常、減少資料庫中的重複資料,提高資料庫的性能、可維護性和資料一致性。優點:
- 減少資料冗餘
- 提高資料一致性
- 提高資料庫性能
- 更方便維護資料
- 更方便查詢
- 更容易擴充
- 資料表數量增加、增加更多關聯
- 需要更多 Join 語法,有時可能降低效能
- 不適合全部場景
常見的正規化種類
資料庫正規化常見的有以下幾種,由上往下分別是:- 第一正規化
- 第二正規化
- 第三正規化
- 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
太感谢了,之前一直不理解1nf 2nf 3nf的关系,现在清晰一点了
回覆刪除