一個表格要算是達到第二正規化,必須:
- 它已經在 第一正規化 (1NF) 裡了。
- 每個非主鍵欄位都要 依賴整個主鍵,而不是只依賴主鍵的一部分。
如果主鍵是由多個欄位組成(複合主鍵),那任何非主鍵屬性(欄位)都不能只依賴主鍵的一部分。換句話說,2NF 就是要消除 部分依賴。
違反 2NF 的範例
假設我們有一個 student_courses(學生與課程)表格,裡面存著學生、他們的課程還有老師的資訊:
| student_id | course_id | course_name | instructor_name |
|---|---|---|---|
| 1 | 101 | 數學 | Lin |
| 1 | 102 | 文學 | Song |
| 2 | 101 | 數學 | Lin |
student_id跟course_id一起組成複合主鍵。- 但注意
course_name跟instructor_name這兩個欄位。它們只依賴course_id,而不是整個 (student_id,course_id) 這對主鍵。
這就是部分依賴啦!course_name 跟 instructor_name 只依賴複合主鍵的一部分(course_id)。這樣就違反 2NF 的原則了。
讓表格符合 2NF
我們的任務就是要消除部分依賴,把表格拆成兩個。這樣可以去除重複,讓資料一致性更好。
把課程的資訊獨立出來,變成一個 courses 表格:
| course_id | course_name | instructor_name |
|---|---|---|
| 101 | 數學 | Lin |
| 102 | 文學 | Song |
主要的表格就變成這樣:
| student_id | course_id |
|---|---|
| 1 | 101 |
| 1 | 102 |
| 2 | 101 |
現在每個欄位都依賴 整個主鍵。我們把資料分開,讓每一筆資訊都邏輯上有關聯,也消除了 2NF 的違規。
消除重複的魔法
注意看正規化前的表格。instructor_name 欄位裡 "Lin" 這個名字一直重複。想像一下,如果資料庫有幾千筆資料,這種重複會有多少?把表格拆開後,我們就消除了重複,也減少了出錯的機會,比如拼錯("Lin" vs "Ling")。
生活中的例子
想像你在管理商品訂單。有一個 order_items(訂單與商品)表格,order_id 跟 item_id 是主鍵:
| order_id | item_id | item_name | price |
|---|---|---|---|
| 1 | 101 | 筆電 | 50000 |
| 1 | 102 | 滑鼠 | 1000 |
| 2 | 101 | 筆電 | 50000 |
你看,商品名稱跟價格都重複了。這就是 2NF 違規,因為 item_name 跟 price 只依賴 item_id。
要讓表格符合 2NF,就要建立一個 items 表格:
| item_id | item_name | price |
|---|---|---|
| 101 | 筆電 | 50000 |
| 102 | 滑鼠 | 1000 |
然後把 order_items 表格改成只留訂單跟商品的 id:
| order_id | item_id |
|---|---|
| 1 | 101 |
| 1 | 102 |
| 2 | 101 |
現在資料就像 code review 後一樣乾淨——完全沒有重複。
實作練習:你也來試試!
假設你有一個 employee_projects 表格,裡面有員工、他們的專案還有專案經理的資訊:
| employee_id | project_id | project_name | manager_name |
|---|---|---|---|
| 1 | 201 | CRM 升級 | Lin |
| 2 | 202 | 網站改版 | Ming |
| 1 | 202 | 網站改版 | Ming |
試試看:
- 找出違反 2NF 的依賴。
- 把表格拆成兩個,消除違規。
為什麼要遵守 2NF?
為什麼要遵守第二正規化 (2NF) 呢?很簡單:就是為了避免資料重複、減少混亂。當你消除部分依賴,表格就會變得更乾淨——不會有一堆重複的資訊,比如每一行都出現同一個老師的名字。這樣可以省空間,也不怕資料不一致:只要在一個地方改名字,全部都會跟著更新。
而且,這樣的資料庫查詢也比較簡單:結構有邏輯、資料不會分散在一堆行裡,filter 跟 group by 都會更快更穩。沒錯,這樣會多一些 SQL JOIN,因為表格變多了。但總比一堆重複的名字好吧?大多數情況下,正規化真的值得。
跟實際專案的結合
你會在哪些地方用到 2NF?
- 設計資料庫時: 幫你避免表格亂成一團。
- 面試的時候: 很常被問要解釋或把表格正規化。
- 實際工作上: 當你要優化現有資料庫,把「巨石」表格拆成正規化的表。
第二正規化 (2NF) 幫你消除複合主鍵表格裡的部分依賴。我們把表格拆成有邏輯的區塊,讓每個欄位都只依賴整個主鍵,而不是主鍵的一部分。這樣可以提升資料庫品質、消除重複、讓它更有彈性。準備好進入第三正規化了嗎?繼續往下看吧!
GO TO FULL VERSION