CodeGym /課程 /SQL SELF /第三正規化原則 (3NF)

第三正規化原則 (3NF)

SQL SELF
等級 25 , 課堂 3
開放

第三正規化 (3NF) 就是讓我們的資料更有秩序的一步。簡單說,一個 table 要在 3NF,得符合:

  1. 它已經在 第二正規化 (2NF)
  2. 所有非主鍵屬性 只依賴主鍵,不能依賴其他東西(不能有傳遞依賴!)。

換句話說,3NF 要求 table 裡的所有資料都要直接跟主鍵有關,不能依賴其他非主鍵屬性。

傳遞依賴就是,屬性 A 依賴屬性 B,B 又依賴屬性 C,這樣就有一條依賴鏈 A → B → C。舉例來說,「員工」依賴「部門」,「部門」又依賴「位置」。所以「員工」就傳遞依賴「位置」。

3NF 違規範例

假設我們有個 employees table,裡面存員工資料:

employee_id name department department_manager
1 Otto Lin Marketing Leo Zhang
2 Alex Song Finance Maria Chi
3 Anna Ming Finance Maria Chi

這裡:

  • employee_id — 主鍵。
  • departmentdepartment_manager — 非主鍵屬性。

乍看之下沒問題,但仔細看會發現:department_manager 不是依賴 employee_id,而是依賴 department。這樣就有傳遞依賴:employee_id → department → department_manager

可能遇到的問題

如果我們要改部門經理(像「Finance」),就得更新所有有這個部門的 row。如果不小心漏掉一個,資料就不一致了。這種麻煩完全可以避免。

讓 table 達到 3NF

為了消除傳遞依賴,我們把 table 拆成兩個:一個存員工資料,一個存部門資料。

employees table

employee_id name department
1 Otto Lin 行銷
2 Alex Song 財務
3 Anna Ming 財務

departments table

department department_manager
行銷 Leo Zhang
財務 Maria Chi

現在一切都很有條理,每個 table 各司其職:

  1. employees table 存員工資料。
  2. departments table 存部門跟經理資料。

如果部門經理換人,只要改 departments table 的一行,不用改所有員工的資料。

怎麼判斷 table 違反 3NF?

要判斷 table 有沒有違反 3NF,可以檢查:

  1. table 裡有沒有傳遞依賴?像屬性 A 依賴 B,B 又依賴 C。
  2. 所有非主鍵屬性是不是都直接依賴主鍵?如果有東西依賴其他非主鍵屬性,那就不是 3NF。

實戰範例:商店

來看一個 sales table,裡面有銷售資料:

sale_id product_name product_price customer_name
1 手機 20 000 Otto Lin
2 筆電 50 000 Alex Song
3 手機 20 000 Anna Ming

這裡很明顯有重複:商品價格資訊每次銷售都重複。如果價格變了,資料馬上就不一致。

為了消除 3NF 違規,我們把 table 拆成兩個:

  1. sales table 存銷售資料。
  2. products table 存商品跟價格。

sales table

sale_id product_id customer_name
1 1 Otto Lin
2 2 Alex Song
3 1 Anna Ming

products table

product_id product_name product_price
1 手機 20 000
2 筆電 50 000

現在如果商品價格變了,只要改 products table 的一行,資料就還是很一致。

實作練習

來個小挑戰:你有個 students_courses table,長這樣:

student_id student_name course_name teacher_name
1 Otto Lin 數學 Maria Chi
2 Alex Song 程式設計 Leo Zhang
1 Otto Lin 程式設計 Leo Zhang

請把這個 table 拆成符合 3NF。提示:你需要建立三個 table(studentscoursesteachers),然後正確連結它們。

為什麼要遵守 3NF?

為什麼要在意第三正規化 (3NF)?因為它真的讓人生簡單很多。table 達到 3NF,資料就很乾淨——沒有多餘重複,也比較不會出錯。更新資料也快又簡單,因為東西只存一份,不用到處複製貼上。

而且資料庫結構也更彈性。想加新欄位或改舊的,不用大改整個系統。

不過就像所有好故事一樣,有個小提醒:太過頭的正規化會讓 table 變超多,查詢時 JOIN 一堆,有時真的會慢。所以重點是拿捏好。該正規化就正規化,該留點重複也不用怕。

接下來我們會更深入:學怎麼正確建立 table 關聯,打造又方便又可靠的資料庫。衝吧,做出超棒的資料庫設計!

留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION