er_database
ER 資料庫正規化
目的 留言 編輯此處
其目的是為了降低資料的「重覆性」與避免「更新異常」的情況發生。

1NF(First normal form)
- 一格(每一列每一欄)只能有一筆資料
- 每筆資料都有一個唯一的主鍵作為識別
2NF (Second normal form)
- 符合1NF
- 消除部分相依
3NF (Third normal form)
- 符合1NF及2NF
- 消除遞移相依
1NF(First normal form)
- 避免欄位長度無法確定
- 避免出現完全一樣的兩筆資料
資料庫正規化(Database normalization)
目的
其目的是為了降低資料的「重覆性」與避免「更新異常」的情況發生。
範例訂單
| 購買日期 | 客戶ID | 客戶名稱 | 商品名稱 | 單價 | 量(斤) |
|---|---|---|---|---|---|
| 12/24 | p001 | Ken | 香蕉 | 10 | 5 |
| 12/24 | p002 | Howard | 蘋果,香蕉,橘子 | 30,10,20 | 2,4,1 |
| 12/25 | p003 | Chris | 蘋果 | 30 | 2 |
| 12/25 | p003 | Chris | 蘋果 | 30 | 2 |
| 12/25 | p004 | May | 蘋果,橘子 | 30,20 | 1,1 |
1NF(First normal form)
- 一格(每一列每一欄)只能有一筆資料
- 每筆資料都有一個唯一的主鍵作為識別
2NF (Second normal form)
- 符合1NF
- 消除部分相依
3NF (Third normal form)
- 符合1NF及2NF
- 消除遞移相依
1NF
- 避免欄位長度無法確定
- 避免出現完全一樣的兩筆資料
首先將欄位中有多重資料的訂單拆開,然後給每一筆訂單一個唯一鍵
| 購買日期 | 客戶ID | 客戶名稱 | 商品名稱 | 單價 | 量(斤) |
|---|---|---|---|---|---|
| 12/24 | p002 | Howard | 蘋果,香蕉,橘子 | 30,10,20 | 2,4,1 |
| 購買日期 | 客戶ID | 客戶名稱 | 商品名稱 | 單價 | 量(斤) |
|---|---|---|---|---|---|
| 12/24 | p002 | Howard | 蘋果 | 30 | 2 |
| 12/24 | p002 | Howard | 香蕉 | 10 | 4 |
| 12/24 | p002 | Howard | 橘子 | 20 | 1 |
下表是我第一次正規化的結果
| 編號 | 購買日期 | 客戶ID | 客戶名稱 | 商品名稱 | 單價 | 量(斤) |
|---|---|---|---|---|---|---|
| 1 | 12/24 | p001 | Ken | 香蕉 | 10 | 5 |
| 2 | 12/24 | p002 | Howard | 蘋果 | 30 | 2 |
| 3 | 12/24 | p002 | Howard | 香蕉 | 10 | 4 |
| 4 | 12/24 | p002 | Howard | 橘子 | 20 | 1 |
| 5 | 12/25 | p003 | Chris | 蘋果 | 30 | 2 |
| 6 | 12/25 | p003 | Chris | 蘋果 | 30 | 2 |
| 7 | 12/25 | p004 | May | 蘋果 | 30 | 1 |
| 8 | 12/25 | p004 | May | 橘子 | 20 | 1 |
失去原本的資料的真實性了,看不出來其實002~004其實是同一筆訂單了,其他多筆資料的訂單也是,所以再弄成下面這樣
訂單
| 編號 | 訂單編號 | 購買日期 | 客戶ID | 客戶名稱 | 商品名稱 | 單價 | 量(斤) |
|---|---|---|---|---|---|---|---|
| 1 | d001 | 12/24 | p001 | Ken | 香蕉 | 10 | 5 |
| 2 | d002 | 12/24 | p002 | Howard | 蘋果 | 30 | 2 |
| 3 | d002 | 12/24 | p002 | Howard | 香蕉 | 10 | 4 |
| 4 | d002 | 12/24 | p002 | Howard | 橘子 | 20 | 1 |
| 5 | d003 | 12/25 | p003 | Chris | 蘋果 | 30 | 2 |
| 6 | d004 | 12/25 | p003 | Chris | 蘋果 | 30 | 2 |
| 7 | d005 | 12/25 | p004 | May | 蘋果 | 30 | 1 |
| 8 | d005 | 12/25 | p004 | May | 橘子 | 20 | 1 |
感覺資料變更多了啊!!!
2NF
消除部分相依
- 將商品名稱與單價獨立出來
訂單
| 編號 | 訂單編號 | 購買日期 | 客戶ID | 客戶名稱 | 商品名稱 | 量(斤) |
|---|---|---|---|---|---|---|
| 1 | d001 | 12/24 | p001 | Ken | 香蕉 | 5 |
| 2 | d002 | 12/24 | p002 | Howard | 蘋果 | 2 |
| 3 | d002 | 12/24 | p002 | Howard | 香蕉 | 4 |
| 4 | d002 | 12/24 | p002 | Howard | 橘子 | 1 |
| 5 | d003 | 12/25 | p003 | Chris | 蘋果 | 2 |
| 6 | d004 | 12/25 | p003 | Chris | 蘋果 | 2 |
| 7 | d005 | 12/25 | p004 | May | 蘋果 | 1 |
| 8 | d005 | 12/25 | p004 | May | 橘子 | 1 |
商品資訊
| 商品名稱 | 單價 |
|---|---|
| 香蕉 | 10 |
| 蘋果 | 30 |
| 橘子 | 20 |
3NF
消除遞移相依
- 何謂遞移相依?
X->Y,Y->Z 所以X->Z - 將客戶ID與客戶名稱獨立出來
訂單
| 編號 | 訂單編號 | 購買日期 | 客戶ID | 商品名稱 | 量(斤) |
|---|---|---|---|---|---|
| 1 | d001 | 12/24 | p001 | 香蕉 | 5 |
| 2 | d002 | 12/24 | p002 | 蘋果 | 2 |
| 3 | d002 | 12/24 | p002 | 香蕉 | 4 |
| 4 | d002 | 12/24 | p002 | 橘子 | 1 |
| 5 | d003 | 12/25 | p003 | 蘋果 | 2 |
| 6 | d004 | 12/25 | p003 | 蘋果 | 2 |
| 7 | d005 | 12/25 | p004 | 蘋果 | 1 |
| 8 | d005 | 12/25 | p004 | 橘子 | 1 |
客戶資料
| 客戶ID | 客戶名稱 |
|---|---|
| p001 | Ken |
| p002 | Howard |
| p003 | Chris |
| p004 | May |
商品資訊
| 商品名稱 | 單價 |
|---|---|
| 香蕉 | 10 |
| 蘋果 | 30 |
| 橘子 | 20 |
正規化練習

- Timesheet(考勤單)要多 所以要取得Invoice(發票)ID,必須把 Invoice的Timesheetid刪掉
- Employee Address1 Address2 違反第一正規化
- Employee ZIP 違反正規化
- 地址在資料庫寫法必須分開為城市 路 巷等等才不違反規定
- Vehicle的EmplyeeID應該與VehicleID形成一個新表
- EmployeeType與Employee應該是1->多
- Salary不屬於Employee
- 因為Timesheet中有ClientID所以Client對TimeSheet應該要有一條 1->多
修改版
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.