# 資料庫正規化

可參考這篇PPTopen in new window,若讀起來很吃力就先往下看吧~

  • 資料庫正規化(Database Normalization)

這篇主要是面相給初學者,所以覺得很冗長是正常的!我認為這塊用逆向思維來學比較容易記住。

  • Normal Form 簡稱 NF

一些課本開頭都說正規化有什麼好處 blablabla,但對於第一次學的人沒什麼感覺(心理 OS: 喔是喔~然後下個月就忘記了)

# 我們換個方式來學習

  • 這邊有一個表格HOLO生課程資料,請試著幫我將 PHP 學分改成3學分
學號姓名性別課程名稱學分必選修成績老師姓名
S3A517001GuraPHP,JS2,3必,必74,59阿錢,阿許
S3A517002InaPHP,UI/UX2,2必,選88,80阿錢,阿陳

You: 這很簡單啊 改 2 筆就好

  • 那如果今天有 300 筆呢?1000 筆呢?改起來要花幾分鐘呢?

  • 再換一個問題幫我新增一個課程 jQuery 2學分 必修

You: 好了!

學號姓名性別課程名稱學分必選修成績老師姓名
NULLNULLNULLjQuery2必修NULLNULL

沒給我學生和其他資料 新增個毛線阿 這看起來很奇怪對吧!因為資料都黏在一起(耦合太強)。

# 不好的設計會導致 異常狀況(Anomaly)

  • 更新異常 ex 改 PHP 學分 2=>3 要改很多筆資料
  • 插入異常 ex 只想新增 jQuery 課程發現缺一堆資料
  • 刪除異常 ex 刪除一位學生 成績記錄就沒了

# 工程師很懶的

我們想設計好維護的表(Table)透過上面的例子應該會發現一件事--那就是應該分類!

若將表拆成很細,最後透過電腦組合起來就好了,這也是正規化在做的事情。

不要死記,用理解的,痛過才會花時間找方法精進。


# 1NF 一階正規化

  • 單欄位不能有 2 筆以上的資料,即單一值(Atomic)
  • 每筆資料不能重複(完全一樣)
  • 資料要有主鍵(PK)

TIP

把多資料拆掉,雖然資料變多但是更清楚了

學號姓名性別課程名稱學分必選修成績老師姓名
S3A517001GuraPHP2必修74阿錢
S3A517001GuraJS3必修59阿許
S3A517002InaPHP2必修88阿錢
S3A517002InaUI/UX2選修80阿陳
[收合/展開] PK FK 是?
  • PK (Primary Key) 中文:主鍵
    • 就是唯一值例如身分證字號,學號都只會有一個,這樣就不會找錯人
  • FK (Foreign Key) 中文:外鍵
    • 可以先記成一個代號,透過這個代號可以取得很多相關的資料

範例如下

PK=蝦皮訂單 idFK=下單帳號日期數量物品單價
1dpes86931997/12/072PS520000
2hentai1232022/05/011PS410000
PK=帳號名稱信箱
dpes8693Richarddpes8693@gmail.com
hentai123態變太hentai123@gmail.com

# 2NF 二階正規化

  • 符合 1NF
  • 將部分相依的資料拆分出去(分類分起來)

TIP

先把學生拆出來

學號姓名性別
S3A517001Gura
S3A517002Ina
課程名稱學分必選修成績老師姓名
PHP2必修74阿錢
JS3必修59阿許
PHP2必修88阿錢
UI/UX2選修80阿陳

TIP

之後再拆 課程 成績 變成三部分(課程補上編號)

課程編號課程名稱學分必選修老師姓名
C001PHP2必修阿錢
C002JS3必修阿許
C001PHP2必修阿錢
A001UI/UX2選修阿陳
學號課程編號成績
S3A517001C00174
S3A517001C00259
S3A517002C00188
S3A517002A00180
[收合/展開] 相依有幾種?
  • 完全相依
  • 部分相依
  • 遞移相依(間接相依)

很暴力的解說[相依]: 沒有它就廢掉了,因為無法辨別... 怎麼說呢?

EX: ID | NAME | TEL. 01 | JACK | 0911111111 02 | JACK | 0922222222 請你把 ID 這列遮起來,告訴我 JACK 的電話是幾號 無法辨別 因為有 2 個人 所以需要 PK

# 3NF 三階正規化

  • 符合 2NF
  • 各欄位與 PK 沒有遞移相依
課程編號課程名稱學分必選修老師姓名老師編號
C001PHP2必修阿錢T002
C002JS3必修阿許T001
C001PHP2必修阿錢T002
A001UI/UX2選修阿陳T003

TIP

加入老師編號後 發現 老師姓名 有遞移關係,應該將老師抽出來,未來比較好擴充

課程編號課程名稱學分必選修老師編號
C001PHP2必修T002
C002JS3必修T001
C001PHP2必修T002
A001UI/UX2選修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

ERD img exampleopen in new window

資料庫設計筆記open in new window

[資料庫] 關聯介紹 一對一、一對多、多對多open in new window

Last Updated: 2022/7/25 下午12:05:42
Contributors: Richard Lin