# 資料庫正規化
可參考這篇PPTopen in new window,若讀起來很吃力就先往下看吧~
- 資料庫正規化(Database Normalization)
這篇主要是面相給初學者,所以覺得很冗長是正常的!我認為這塊用逆向思維來學比較容易記住。
- Normal Form 簡稱 NF
一些課本開頭都說正規化有什麼好處 blablabla,但對於第一次學的人沒什麼感覺(心理 OS: 喔是喔~然後下個月就忘記了)
# 我們換個方式來學習
- 這邊有一個表格
HOLO生課程資料
,請試著幫我將 PHP 學分改成3學分
學號 | 姓名 | 性別 | 課程名稱 | 學分 | 必選修 | 成績 | 老師姓名 |
---|---|---|---|---|---|---|---|
S3A517001 | Gura | 女 | PHP,JS | 2,3 | 必,必 | 74,59 | 阿錢,阿許 |
S3A517002 | Ina | 女 | PHP,UI/UX | 2,2 | 必,選 | 88,80 | 阿錢,阿陳 |
You: 這很簡單啊 改 2 筆就好
那如果今天有 300 筆呢?1000 筆呢?改起來要花幾分鐘呢?
再換一個問題幫我新增一個課程
jQuery 2學分 必修
You: 好了!
學號 | 姓名 | 性別 | 課程名稱 | 學分 | 必選修 | 成績 | 老師姓名 |
---|---|---|---|---|---|---|---|
NULL | NULL | NULL | jQuery | 2 | 必修 | NULL | NULL |
沒給我學生和其他資料 新增個毛線阿 這看起來很奇怪對吧!因為資料都黏在一起(耦合太強)。
# 不好的設計會導致 異常狀況(Anomaly)
- 更新異常 ex 改 PHP 學分 2=>3 要改很多筆資料
- 插入異常 ex 只想新增 jQuery 課程發現缺一堆資料
- 刪除異常 ex 刪除一位學生 成績記錄就沒了
# 工程師很懶的
我們想設計好維護的表(Table)透過上面的例子應該會發現一件事--那就是應該分類!
若將表拆成很細,最後透過電腦組合起來就好了,這也是正規化在做的事情。
不要死記,用理解的,痛過才會花時間找方法精進。
# 1NF 一階正規化
- 單欄位不能有 2 筆以上的資料,即單一值(Atomic)
- 每筆資料不能重複(完全一樣)
- 資料要有主鍵(PK)
TIP
把多資料拆掉,雖然資料變多但是更清楚了
學號 | 姓名 | 性別 | 課程名稱 | 學分 | 必選修 | 成績 | 老師姓名 |
---|---|---|---|---|---|---|---|
S3A517001 | Gura | 女 | PHP | 2 | 必修 | 74 | 阿錢 |
S3A517001 | Gura | 女 | JS | 3 | 必修 | 59 | 阿許 |
S3A517002 | Ina | 女 | PHP | 2 | 必修 | 88 | 阿錢 |
S3A517002 | Ina | 女 | UI/UX | 2 | 選修 | 80 | 阿陳 |
[收合/展開] PK FK 是?
- PK (Primary Key) 中文:主鍵
- 就是唯一值例如身分證字號,學號都只會有一個,這樣就不會找錯人
- FK (Foreign Key) 中文:外鍵
- 可以先記成一個代號,透過這個代號可以取得很多相關的資料
範例如下
PK=蝦皮訂單 id | FK=下單帳號 | 日期 | 數量 | 物品 | 單價 |
---|---|---|---|---|---|
1 | dpes8693 | 1997/12/07 | 2 | PS5 | 20000 |
2 | hentai123 | 2022/05/01 | 1 | PS4 | 10000 |
PK=帳號 | 名稱 | 信箱 |
---|---|---|
dpes8693 | Richard | dpes8693@gmail.com |
hentai123 | 態變太 | hentai123@gmail.com |
# 2NF 二階正規化
- 符合 1NF
- 將部分相依的資料拆分出去(分類分起來)
TIP
先把學生
拆出來
學號 | 姓名 | 性別 |
---|---|---|
S3A517001 | Gura | 女 |
S3A517002 | Ina | 女 |
課程名稱 | 學分 | 必選修 | 成績 | 老師姓名 |
---|---|---|---|---|
PHP | 2 | 必修 | 74 | 阿錢 |
JS | 3 | 必修 | 59 | 阿許 |
PHP | 2 | 必修 | 88 | 阿錢 |
UI/UX | 2 | 選修 | 80 | 阿陳 |
TIP
之後再拆 課程
成績
變成三部分(課程補上編號)
課程編號 | 課程名稱 | 學分 | 必選修 | 老師姓名 |
---|---|---|---|---|
C001 | PHP | 2 | 必修 | 阿錢 |
C002 | JS | 3 | 必修 | 阿許 |
C001 | PHP | 2 | 必修 | 阿錢 |
A001 | UI/UX | 2 | 選修 | 阿陳 |
學號 | 課程編號 | 成績 |
---|---|---|
S3A517001 | C001 | 74 |
S3A517001 | C002 | 59 |
S3A517002 | C001 | 88 |
S3A517002 | A001 | 80 |
[收合/展開] 相依有幾種?
- 完全相依
- 部分相依
- 遞移相依(間接相依)
很暴力的解說[相依]: 沒有它就廢掉了,因為無法辨別... 怎麼說呢?
EX: ID | NAME | TEL. 01 | JACK | 0911111111 02 | JACK | 0922222222 請你把 ID 這列遮起來,告訴我 JACK 的電話是幾號 無法辨別 因為有 2 個人 所以需要 PK
# 3NF 三階正規化
- 符合 2NF
- 各欄位與 PK 沒有遞移相依
課程編號 | 課程名稱 | 學分 | 必選修 | 老師姓名 | 老師編號 |
---|---|---|---|---|---|
C001 | PHP | 2 | 必修 | 阿錢 | T002 |
C002 | JS | 3 | 必修 | 阿許 | T001 |
C001 | PHP | 2 | 必修 | 阿錢 | T002 |
A001 | UI/UX | 2 | 選修 | 阿陳 | T003 |
TIP
加入老師編號
後 發現 老師姓名
有遞移關係,應該將老師抽出來,未來比較好擴充
課程編號 | 課程名稱 | 學分 | 必選修 | 老師編號 |
---|---|---|---|---|
C001 | PHP | 2 | 必修 | T002 |
C002 | JS | 3 | 必修 | T001 |
C001 | PHP | 2 | 必修 | T002 |
A001 | UI/UX | 2 | 選修 | T003 |
老師編號 | 老師姓名 |
---|---|
T002 | 阿錢 |
T001 | 阿許 |
T002 | 阿錢 |
T003 | 阿陳 |
TIP
從原本的 1 張表 拆成 4 張表 擴充性大幅提升! 回到上面問的 2 個問題
- 請試著幫我將 PHP 學分改成
3學分
- 幫我新增一個課程
jQuery 2學分 必修
是不是都只要改一次就好了呢?
# 其他正規化 有興趣可以搜尋
- 4NF
- 5NF
- BCNF
# 參考資料
Is ERD considered a kind of UML diagram?open in new window