|
|關聯式資料庫|Index|Key|SQL (1)|SQL (2)|SQL (3)|SQL (4)|SQL (5)| |
|
資料庫簡介 |
|
資料正規化
|
何謂正規化 |
|
將表格細分成多個更小的表格,直到每個表格只描述一種事實為止,這一連串的調整過程就稱為資料正規化(Normalization)。 |
目的 |
|
正規化的目的何在?簡單的說就是要將資料的重覆性降至最低(避免資料重複的狀況發生)。倘若在不同的表格中都有學生的姓名時,一旦有個學生改名了,則必須同步更改多個表格的內容;修改的過程中若稍有遺漏,有些資料沒更正,就會發生不一致的狀況。因此,避免資料重複是相當重要的。 |
步驟 |
|
第一正規化(First Normal Form,簡稱 1NF。由 E. F. Codd 提出) |
|
第二正規化(Second Normal Form,簡稱 2NF。由 E. F. Codd 提出) |
|
第三正規化(Third Normal Form,簡稱 3NF。由 E. F. Codd 提出) |
|
Boyce/Codd 正規化(Boyce/Codd Normal Form,簡稱 BCNF。由 R. F. Boyce 與 E. F. Codd 共同提出) |
|
第四正規化(Fourth Normal Form,簡稱 4NF。由 R. Fagin 提出) |
|
第五正規化(Fifth Normal Form,簡稱 5NF。由 R. Fagin 提出) |
實例探討 |
|
假設我們將要設計一個成績單郵寄列印系統,需要學號、地址、郵遞區號、學科代碼與各科成績等資料,而初步搜集到的原始資料如下表所示: |
| Stu_no |
City |
ZIP |
Subject_no, Score |
| 75312 |
台中市 |
400 |
(S5302, 89), (S5345, 90), (S8005, 78), (S3581, 80), (M1201, 65), (M5251, 95) |
| 75524 |
高雄市 |
800 |
(S5302, 88) |
| 75302 |
高雄縣 |
830 |
(S5302, 98), (S5345, 90), (S3581, 84), (M5251, 85) |
|
|
接下來,我們將依序探討 1NF, 2NF 與 3NF 的過程。 |
|
第一正規化(First Normal Form)
|
條件 |
|
第一正規化的表格最重要的是能滿足「每個欄位只能含有一個值」這個條件。 |
正規化 |
|
原始表格: |
| Stu_no |
City |
ZIP |
Subject_no, Score |
| 75312 |
台中市 |
400 |
(S5302, 89), (S5345, 90), (S8005, 78), (S3581, 80), (M1201, 65), (M5251, 95) |
| 75524 |
高雄市 |
800 |
(S5302, 88) |
| 75302 |
高雄縣 |
830 |
(S5302, 98), (S5345, 90), (S3581, 84), (M5251, 85) |
|
在正規化之後,我們將表格命名為 A: |
《A》
| Stu_no |
City |
ZIP |
Subject_no |
Score |
| 75312 |
台中市 |
400 |
S5302 |
89 |
| 75312 |
台中市 |
400 |
S5345 |
90 |
| 75312 |
台中市 |
400 |
S8005 |
78 |
| 75312 |
台中市 |
400 |
S3581 |
80 |
| 75312 |
台中市 |
400 |
M1201 |
65 |
| 75312 |
台中市 |
400 |
M5251 |
95 |
| 75524 |
高雄市 |
800 |
S5302 |
88 |
| 75302 |
高雄縣 |
830 |
S5302 |
98 |
| 75302 |
高雄縣 |
830 |
S5345 |
90 |
| 75302 |
高雄縣 |
830 |
S3581 |
84 |
| 75302 |
高雄縣 |
830 |
M5251 |
85 |
|
結果探討 |
|
在同一學生只能選修同科目一次的條件下,「Stu_no」加上「Subject_no」可以做為 A 的主鍵(Primary key)。我們以下圖來說明主鍵與其他欄位之間在功能上的相依關係(Functional Dependency): |
 |
|
在 A 之中係以(Stu_no, Subject_no)為 Primary key,但從上圖看來,有三項「功能相依」關係是錯誤的(如紅線所示),City 與 ZIP 的值與 Subject_no 絲毫無關。 |
在這樣的架構下,將產生下列問題:
- 無法單獨新增一筆學生資料。因為 Subject_no 是 Primary key 之一,不能為空值(Null);因此,一個未修習任何課程學生的資料,將無法寫入 A。
- 無法單獨刪除一筆成績資料。如果我們打算刪除(75524, S5302)這筆資料的話,該生的地址資料也將一併消失。
- 需要同步異動的資料太多。假如 75312 這個學生搬家了,那麼我們得異動其中的 6 筆紀錄。
|
|
因此,我們得繼續進行 2NF。 |
|
第二正規化(Second Normal Form)
|
條件 |
|
一個表格必須滿意第一正規化的條件,並且非主鍵的欄位都要對主鍵有「完全地功能性相依(Fully Functional Dependency)」關係,才能算是達到第二正規化。 |
正規化 |
|
已合乎 1NF 的表格 A: |
| Stu_no |
City |
ZIP |
Subject_no |
Score |
| 75312 |
台中市 |
400 |
S5302 |
89 |
| 75312 |
台中市 |
400 |
S5345 |
90 |
| 75312 |
台中市 |
400 |
S8005 |
78 |
| 75312 |
台中市 |
400 |
S3581 |
80 |
| 75312 |
台中市 |
400 |
M1201 |
65 |
| 75312 |
台中市 |
400 |
M5251 |
95 |
| 75524 |
高雄市 |
800 |
S5302 |
88 |
| 75302 |
高雄縣 |
830 |
S5302 |
98 |
| 75302 |
高雄縣 |
830 |
S5345 |
90 |
| 75302 |
高雄縣 |
830 |
S3581 |
84 |
| 75302 |
高雄縣 |
830 |
M5251 |
85 |
|
在正規化之後,我們將表格 A 一分為二,並分別命名為 B1 與 B2: |
《B1》
| Stu_no |
City |
ZIP |
| 75312 |
台中市 |
400 |
| 75524 |
高雄市 |
800 |
| 75302 |
高雄縣 |
830 |
|
《B2》
| Stu_no |
Subject_no |
Score |
| 75312 |
S5302 |
89 |
| 75312 |
S5345 |
90 |
| 75312 |
S8005 |
78 |
| 75312 |
S3581 |
80 |
| 75312 |
M1201 |
65 |
| 75312 |
M5251 |
95 |
| 75524 |
S5302 |
88 |
| 75302 |
S5302 |
98 |
| 75302 |
S5345 |
90 |
| 75302 |
S3581 |
84 |
| 75302 |
M5251 |
85 |
|
|---|
|
結果探討 |
|
在經過 2NF 之後,先前的「無法單獨新增一筆學生資料」與「無法單獨刪除一筆成績資料」的問題都解決了。我們再看看 B1 與 B2 各欄位和主鍵之間在功能上的相依關係(Functional Dependency): |


|
|
在一個表格中,如果某一欄位值可決定其他欄位值;而這些欄位中又存在某一欄位可以決定剩餘欄位的值,稱為「遞移相依性(Transitive Dependency)」。若有此一情況發生,在異動資料時,可能會造成其他資料不一致的現象。 |
|
在 B1 之中便有「遞移相依性」關係存在:B1.Stu_no -> B1.City 且 B1.City -> B1.ZIP 。 |
在這樣的架構下,將產生下列問題:
- 無法單獨新增一筆縣市資料。因為 Stu_no 是 Primary key,不能為空值(Null);因此,若無任何學生居住的某個縣市,其郵遞區號資料將無法被事先建立。
- 無法單獨刪除一筆學生資料。如果我們打算刪除 75524 這筆資料的話,該生所在的高雄市郵遞區號資料也將一併消失。
- 仍有需要同步異動的資料。假如台中市的郵遞區號修改了,且住在該地區的學生又不只一位時,那麼我們又得異動多筆紀錄了。
|
|
因此,我們還得繼續進行 3NF。 |
|
第三正規化(Third Normal Form)
|
條件 |
|
一個表格必須滿意第二正規化的條件,並且消除「遞移相依」現象,意即非主鍵的欄位之間沒有「完全地功能性相依」關係,才能算是達到第三正規化。 |
正規化 |
|
已合乎 2NF 的表格 B1: |
| Stu_no |
City |
ZIP |
| 75312 |
台中市 |
400 |
| 75524 |
高雄市 |
800 |
| 75302 |
高雄縣 |
830 |
|
在正規化之後,我們將表格 B1 再度一分為二,並分別命名為 C1 與 C2: |
《C1》
| Stu_no |
City |
| 75312 |
台中市 |
| 75524 |
高雄市 |
| 75302 |
高雄縣 |
|
《C2》
| City |
ZIP |
| 台中市 |
400 |
| 高雄市 |
800 |
| 高雄縣 |
830 |
|
|---|
|
結果探討 |
|
在經過 3NF 之後,先前的「無法單獨新增一筆縣市資料」與「無法單獨刪除一筆學生資料」的問題都解決了,需要同步異動大量資料的情況似乎也不復存在了。我們再以表格與欄位間的相依關係來看看正規化的結果: |
《C1》
| Stu_no |
City |
| 75312 |
台中市 |
| 75524 |
高雄市 |
| 75302 |
高雄縣 |
|
《C2》
| City |
ZIP |
| 台中市 |
400 |
| 高雄市 |
800 |
| 高雄縣 |
830 |
|
《B2》
| Stu_no |
Subject_no |
Score |
| 75312 |
S5302 |
89 |
| 75312 |
S5345 |
90 |
| 75312 |
S8005 |
78 |
| 75312 |
S3581 |
80 |
| 75312 |
M1201 |
65 |
| 75312 |
M5251 |
95 |
| 75524 |
S5302 |
88 |
| 75302 |
S5302 |
98 |
| 75302 |
S5345 |
90 |
| 75302 |
S3581 |
84 |
| 75302 |
M5251 |
85 |
|
|---|
|



|
|
一般表格進行至第三正規化時,多半沒有什麼狀況了;倘若仍有異常狀況發生,則需繼續進行 BCNF,甚至於 4NF 與 5NF,關於這個部份請自行參閱相關書籍。 |
|
正規化只是建立資料表的原則,而非鐵律。切莫因為過度正規化,反而導致資料存取的效率下降。有時在優先考量執行效率的前提下,我們還必須做適當的反正規化(Denormalize)。 |
|
|
|關聯式資料庫|Index|Key|SQL (1)|SQL (2)|SQL (3)|SQL (4)|SQL (5)| |