# 回到基礎 - 資料庫正規化

資料庫正規化，是設計資料庫的一系列原理，以減少資料庫中資料的冗餘和提升資料的一致性。主要用於關聯式資料庫上，最初由 Edgar F. Codd 所提出。從最初的 UNF 一直到現在的 6NF總共有 11 個階段，但是大部分只會用到 3NF。因為過度的正規化，會造成資料庫的操作複雜性提高很多，所以還是要考量實務上的需求，做不到不同程度的正規化。

以下是擷取自 Wiki 的不同正規化的原則：

![正規化階層表](https://cdn.hashnode.com/res/hashnode/image/upload/v1635952367640/j1sjuuHiu.png)

## 1NF: First normal form 第一正規化
主要原則增加了欄位原子性，每個欄位的值都只有一個值，並且所有欄位都是依賴於 Primary key。
例如每個班級的學生名字都不會有多個，而且名字和性別都是依賴於學號一樣。

還未正規化的資料，可以看到課程名稱和成績都是複數的值。

| 學號 | 姓名  | 性別   | 課程名稱   | 成績   |
|------|-------|--------|------------|--------|
| 001  | Amy   | Female | Design, PE | 15, 14 |
| 002  | David | Male   | Design, PE | 11, 24 |


正規化後

| 學號 | 姓名  | 性別   | 課程名稱 | 成績 |
|------|-------|--------|----------|------|
| 001  | Amy   | Female | Design   | 15   |
| 001  | Amy   | Female | PE       | 14   |
| 002  | David | Male   | Design   | 11   |
| 002  | David | Male   | PE       | 24   |


## 2NF: Second normal form 第二正規化
主要原則增加了每個欄位值都相依於 Primary key，只有當 Pimary key 是複數欄位組成時，才能是部分相依。例如學號跟課程名稱是沒有關係的，進行第二正規化後會變成：

| 學號 | 姓名  | 性別   |
|------|-------|--------|
| 001  | Amy   | Female |
| 002  | David | Male   |

| 學號 | 課程代碼 | 成績 |
|------|----------|------|
| 001  | C001     | 45   |
| 002  | C002     | 14   |

| 課程代碼 | 老師編號 | 課程名稱 | 老師名稱 |
| -------- | -------- | -------- | -------- |
| C001     | T1       | Design   | Mv       |
| C002     | T2       | PE       | Zd       |

## 3NF: Third normal form 第三正規化
Table 中不能有間接依賴，例如老師名稱和課程代碼沒有相關，但是跟老師編號有相關。那老師名稱跟課程代碼就是有間接相依。
第三正規化就是在做拆分，將兩個資料表用 Foreign key 做連結。

| 課程代碼 | 課程名稱 | 老師編號 |
|----------|----------|----------|
| C001      | Design    | T1 |
| C002     | PE            | T2 |

| 老師編號 | 老師名稱 |
| -------- | -------- |
| T1       | Mv       |
| T2       | Zd       |

## EKNF: Elementary key normal form 主鍵正規化

沒找到很好清楚的解釋

## BCNF: Boyce–Codd normal form Boyce-Codd 正規化
由 Boyce 和 Codd 在 1974 年所提出的 3NF 改良版，比 3NF 更嚴苛。如果 Primary key 是由多個欄位組成時，就必須執行 BCNF。其除了 Primary key 之外的欄位，不可以依賴於其他非 Primary key 的欄位。

## 4NF: Fourth normal form 第四正規化
主要著重在組合 primary key 的使用

Primary key 由三個欄位組成，但是可以發現有很多重複的地方。Pizza Variety 和 Delivery Area 都只跟 Restaurant 有相依，但是彼此沒有相關。這種情況下，就會需要進行 4NF。
要符合 4NF 的話就要再拆分

| Restaurant       | Pizza Variety | Delivery Area |
|------------------|---------------|---------------|
| A1 Pizza         | Thick Crust   | Springfield   |
| A1 Pizza         | Thick Crust   | Shelbyville   |
| A1 Pizza         | Thick Crust   | Capital City  |
| A1 Pizza         | Stuffed Crust | Springfield   |
| A1 Pizza         | Stuffed Crust | Shelbyville   |
| A1 Pizza         | Stuffed Crust | Capital City  |
| Elite Pizza      | Thin Crust    | Capital City  |
| Elite Pizza      | Stuffed Crust | Capital City  |
| Vincenzo's Pizza | Thick Crust   | Springfield   |
| Vincenzo's Pizza | Thick Crust   | Shelbyville   |
| Vincenzo's Pizza | Thin Crust    | Springfield   |
| Vincenzo's Pizza | Thin Crust    | Shelbyville   |

經過 4NF 之後

| Restaurant       | Pizza Variety |
|------------------|---------------|
| A1 Pizza         | Thick Crust   |
| A1 Pizza         | Stuffed Crust |
| Elite Pizza      | Thin Crust    |
| Elite Pizza      | Stuffed Crust |
| Vincenzo's Pizza | Thick Crust   |
| Vincenzo's Pizza | Thin Crust    |

| Restaurant       | Delivery Area |
|------------------|---------------|
| A1 Pizza         | Springfield   |
| A1 Pizza         | Shelbyville   |
| A1 Pizza         | Capital City  |
| Elite Pizza      | Capital City  |
| Vincenzo's Pizza | Springfield   |
| Vincenzo's Pizza | Shelbyville   |

## ETNF: Essential tuple normal form 關鍵元祖正規化
Every join dependency has a superkey component
每個 join 的相依都需要有個 foreign key。
個人覺得簡單的解釋就是，在我們所謂的關聯表中，除了 foreign key 之外不加入其他欄位。

| Supplier ID | Title                                                   | Franchisee ID |
|-------------|---------------------------------------------------------|---------------|
| 1           | Beginning MySQL Database Design and Optimization        | 1             |
| 2           | The Relational Model for Database Management: Version 2 | 2             |
| 3           | Learning SQL                                            | 3             |

經過 ETNF 後，拆分成三張表

| Supplier ID | Title                                                   |
|-------------|---------------------------------------------------------|
| 1           | Beginning MySQL Database Design and Optimization        |
| 2           | The Relational Model for Database Management: Version 2 |
| 3           | Learning SQL                                            |

| Title                                                   | Franchisee ID |
|---------------------------------------------------------|---------------|
| Beginning MySQL Database Design and Optimization        | 1             |
| The Relational Model for Database Management: Version 2 | 2             |
| Learning SQL                                            | 3             |

| Supplier ID | Franchisee ID |
|-------------|---------------|
| 1           | 1             |
| 2           | 2             |
| 3           | 3             |

## 5NF: Fifth normal form 第五正規化
Every join dependency has only superkey components	



## DKNF: Domain-key normal form 域鍵正規化
著重在於 constraint

## 6NF: Sixth normal form 第六正規化


## Reference

- https://www.wikiwand.com/en/Database_normalization
- http://cc.cust.edu.tw/~ccchen/doc/db_04.pdf

