終於來到資料庫正規化的最後一章,正規化的規則其實不只到第三正規化,還有第四正規化、第五正規化,但一般來說只要盡可能符合第一到第三正規化,設計的資料庫就能有不錯的效能,接下來就來介紹第三正規化的定義吧。
第三正規化(3NF)
執行第三正規化有兩個核心概念:
- 滿足第一(1NF)及第二正規化(2NF)
- 消除資料表中的遞延相依性
什麼是遞延相依性呢?即資料表中的非鍵值欄位間不存在功能相依性,彼此獨立無關,只跟主鍵值有相依性。舉例來說,一個欄位如果可以用資料表的其他欄位計算出來,就不要設立一個欄位紀錄。
我們一樣以訂單資料表為例,在這張表中有一個subtotal(小計)欄位,欄位中的資料是由qty欄位的值乘以price欄位值得來的。看到這裡發現是不是發現這樣的資料庫設計違反了第三正規化呢? 這裡的subtotal欄位與qty及price這兩個非鍵值欄位產生相依性,而且也與主鍵欄位order_id無關,產生了遞延相依性。更重要的是將subtotal欄位移除掉也不會影響到資料庫完整性,我們只要在需要subtotal值時再計算出來即可。
而且像上圖subtotal的欄位設計,可能會導致「更新異常」。比如說訂單x203要修改購買數量從3個變為4個,而操作只修改了qty欄位而忘了將subtotal欄位更新為800,就會導致資料不一致的問題,造成少收錢的狀況。
當然只要人為不要發失誤,或是後續開發系統邏輯寫得好,就比較不會有問題。但是只要有人的介入就有錯誤的可能,這也是資料庫正規化的目的,運用系統性的規範,盡量避免資料重複、不一致發生的的可能性。
看到這邊你可能會問,資料庫正規化難道沒有缺點嗎?執行正規化簡單來說就是將原本資料表中的欄位按規則拆分,用新的資料表來表示相關性,因此在查詢、更新資料時一定會增加使用Join(關聯)的次數與資料庫查詢指令的複雜度。
因此在設計系統時為了業務需求考量,未必會完全依照三個正規化原則來設計,但還是建議盡量遵循正規化規則,未來在維護資料庫會輕鬆很多。