12月 12, 2019 Database
### 什麼是 Database Normalization

Database Normalization 是一套方法,可以用來幫助你設定好的你的資料庫。它是由幾個規則所組成。

### First normal form

以下是 First normal form (1NF) 的特點 : 

1.	每一個欄位只能有一個單一值。

2.	沒有任何兩筆以上的資料是完全重覆。

3.	資料表中有主鍵, 而其他所有的欄位都相依於「主鍵」。

First normal form (1NF) 是第一個規則,這個規則是規定每一個資料的格子 (Cell) 不可以有多於一個記值存在。例如以下的表格 :

|StudentNumber|StudentName|SubjectName|Teacher|TeacherNumber|Score|
|---|---|---|---|---|---|
|001|Peter|Chinese, English|Mr. Chinese, Mr. English|t01, t02|80, 91|
|002|Mary|Chinese, English|Mr. Chinese, Mr. English|t01, t02|90, 77|
|003|Tom|Chinese, English|Mr. Chinese, Mr. English|t01, t02|100, 55|

在 Score、SubjectName 及 Teacher 的欄位中便有超過一個的值存在著,這樣便和 1NF 的規則違反了。我要需要對這樣的資料進行處理。

最簡單的方法是把重覆的值分別儲存到多個欄位當中。

|StudentNumber|StudentName|SubjectName1|SubjectName2|Teacher1|Teacher2|TeacherNumber1|TeacherNumber2|Score1|Score2|
|---|---|---|---|---|---|---|---|---|---|
|001|Peter|Chinese|English|Mr. Chinese|Mr. English|t01|t02|80|91|
|002|Mary|Chinese|English|Mr. Chinese|Mr. English|t01|t02|90|77|
|003|Tom|Chinese|English|Mr. Chinese|Mr. English|t01|t02|100|55|

這樣的設計就乎合了 1NF 的規則了 ! 可是這不是一個好的設計 ! 因為如果 Subject 的數量是一個不確定的數值,那麽不是要建立一堆空白的欄位來存儲資料?

要解決這個問題,我們需要把資料直向堆疊。資料表變下為以下的模樣 :

|StudentNumber|StudentName|SubjectName|Teacher|TeacherNumber|Score|
|---|---|---|---|---|---|
|001|Peter|Chinese|Mr. Chinese|t01|80|
|001|Peter|English|Mr. English|t02|91|
|002|Mary|Chinese|Mr. Chinese|t01|90|
|002|Mary|English|Mr. English|t02|77|
|003|Tom|Chinese|Mr. Chinese|t01|100|
|003|Tom|English|Mr. English|t02|55|

這樣做也是乎合了 1NF 的規則了 !

### Second normal form

Second normal form (2NF) 的規則是要每一個資料表格內的每個資料值,都要完全相依到它的主鍵 (Primary Key)。看解釋好像很難理解,看看以下實例 : 

經過 1NF 的處理後我們在得到了以下的資料格式。

|StudentNumber|StudentName|SubjectName|Teacher|Score|
|---|---|---|---|---|
|001|Peter|Chinese|Mr. Chinese|80|
|001|Peter|English|Mr. English|91|
|002|Mary|Chinese|Mr. Chinese|90|
|002|Mary|English|Mr. English|77|
|003|Tom|Chinese|Mr. Chinese|100|
|003|Tom|English|Mr. English|55|

上面的資料是用來記錄考績 (Score) 的,而考績是需要主鍵 (Student + Subject) 才能完整關聯得到。相對於 Score 欄位,我們看得到 StudentName 是相依著 StudentNumber。而 Teacher 是相依著 SubjectName 的。即是只有相依到部份的欄位上,需不是完全相依到主鍵 (Student + Subject) 上。

為了要把資料變成為符合 2NF,我們需要把資料分拆成不同的資料表 :

##### Student 資料表

|StudentNumber|StudentName|
|---|---|
|001|Peter|
|002|Mary|
|003|Tom|

##### Subject 資料表

|SubjectName|Teacher|TeacherNumber|
|---|---|---|
|Chinese|Mr. Chinese|t01|
|English|Mr. English|t02|

##### Score 資料表

|StudentNumber|SubjectName|Score|
|---|---|---|
|001|Chinese|80|
|001|English|91|
|002|Chinese|90|
|002|English|77|
|003|Chinese|100|
|003|English|55|

經過 2NF 後,產生三個資料表,分別為 Student 資料表、Subject 資料表
及 Score 資料表。

### Third normal form

Third normal form (3NF) 是要把所有的遞移相依或是間接相依的資料分割出來。什麽是遞移相依? 我們看看以下資料 : 

##### Subject 資料表

|SubjectName|Teacher|TeacherNumber|
|---|---|---|
|Chinese|Mr. Chinese|t01|
|English|Mr. English|t02|

TeacherNumber 是相依到 SubjectName,而 Teacher 可以相依到 TeacherNumber,這樣間 Teacher 也間接相依到 SubjectName。在這個情況就要進行 3NF 把資料從間接相依分割出來。

可以分割出下列資料表格 :

##### Subject 資料表

|SubjectName|TeacherNumber|
|---|---|
|Chinese|t01|
|English|t02|

##### Teacher 資料表

|TeacherNumber|Teacher|
|---|---|
|t01|Mr. Chinese|
|t02|Mr. English|

### 總結

經過使用 Normalization 方法,我們可以把最初的資料 :

|StudentNumber|StudentName|SubjectName|Teacher|TeacherNumber|Score|
|---|---|---|---|---|---|
|001|Peter|Chinese, English|Mr. Chinese, Mr. English|t01, t02|80, 91|
|002|Mary|Chinese, English|Mr. Chinese, Mr. English|t01, t02|90, 77|
|003|Tom|Chinese, English|Mr. Chinese, Mr. English|t01, t02|100, 55|

設計為以下的資料表 : 

##### Student 資料表

|StudentNumber|StudentName|
|---|---|
|001|Peter|
|002|Mary|
|003|Tom|

##### Subject 資料表

|SubjectName|TeacherNumber|
|---|---|
|Chinese|t01|
|English|t02|

##### Teacher 資料表

|TeacherNumber|Teacher|
|---|---|
|t01|Mr. Chinese|
|t02|Mr. English|

##### Score 資料表

|StudentNumber|SubjectName|Score|
|---|---|---|
|001|Chinese|80|
|001|English|91|
|002|Chinese|90|
|002|English|77|
|003|Chinese|100|
|003|English|55|

這裡有個 PowerPoint 是台灣一所大學用來講解 Normalization 的 : 

http://cc.cust.edu.tw/~ccchen/doc/db_04.pdf
過去文章
2025 (9)
4 (5)
3 (1)
2 (3)
2024 (25)
11 (3)
10 (3)
9 (1)
3 (18)
2022 (6)
10 (1)
6 (2)
5 (1)
3 (1)
1 (1)
2021 (21)
11 (7)
7 (1)
6 (2)
5 (2)
4 (6)
3 (2)
2 (1)
2020 (92)
12 (1)
11 (2)
10 (4)
9 (10)
8 (5)
7 (1)
6 (3)
5 (1)
4 (4)
3 (25)
2 (7)
1 (29)
2019 (57)
12 (25)
11 (7)
9 (25)