在前一篇文章中,我們學會了如何把日常資訊轉換成資料表,包括個體表和關係表。
你可能會想:「為什麼要分這麼多張表?好複雜!把所有資料放在一張表不是更簡單嗎?」
這篇文章會回答這個問題。我們會實際嘗試「一張表打天下」,然後你就會明白:為什麼關聯式資料庫要分成多張表。
多張資料表的設計範例
讓我們用前一篇的例子。我們有以下幾張表:
人物表:
| 名稱 | 膚色 |
|---|---|
| David | 深褐色 |
| Emily | 淺褐色 |
| Jason | 淺褐色 |
結婚表:
| 人物一 | 人物二 |
|---|---|
| David | Emily |
朋友表:
| 人物 | 朋友 | 友好程度 |
|---|---|---|
| Jason | David | 高 |
| Jason | Kevin | 中 |
親屬表:
| 人物 | 親屬 | 親屬類型 |
|---|---|---|
| Jason | Emily | 妹妹 |
四張表,看起來有點複雜。可不可以簡單一點?
如果把所有資料放在一張表?
讓我們試試看把所有資料合併成一張表。
第一步:合併人物和結婚
先把人物表和結婚表合併:
| 名稱 | 膚色 | 結婚對象 |
|---|---|---|
| David | 深褐色 | Emily |
| Emily | 淺褐色 | David |
| Jason | 淺褐色 | (無) |
看起來還行?
第二步:合併朋友
再把朋友表合併進來:
| 名稱 | 膚色 | 結婚對象 | 朋友 | 友好程度 |
|---|---|---|---|---|
| David | 深褐色 | Emily | (無) | (無) |
| Emily | 淺褐色 | David | (無) | (無) |
| Jason | 淺褐色 | (無) | David | 高 |
等等,Jason 有兩個朋友(David 和 Kevin),怎麼辦?
第三步:處理多個朋友
如果 Jason 有多個朋友,我們只能再加一列:
| 名稱 | 膚色 | 結婚對象 | 朋友 | 友好程度 |
|---|---|---|---|---|
| David | 深褐色 | Emily | (無) | (無) |
| Emily | 淺褐色 | David | (無) | (無) |
| Jason | 淺褐色 | (無) | David | 高 |
| Jason | 淺褐色 | (無) | Kevin | 中 |
問題來了:Jason 的資料重複了。
「名稱:Jason」和「膚色:淺褐色」出現了兩次。
你可能會說:「重複就重複吧,查詢的時候過濾掉就好了。」
真的沒關係嗎?
重複資料的三大問題
問題一:修改資料很麻煩
假設 Jason 改名叫 Jay,你要改幾個地方?
| 名稱 | 膚色 | 結婚對象 | 朋友 | 友好程度 |
|---|---|---|---|---|
| David | 深褐色 | Emily | (無) | (無) |
| Emily | 淺褐色 | David | (無) | (無) |
| 淺褐色 | (無) | David | 高 | |
| 淺褐色 | (無) | Kevin | 中 |
Jason 有幾個朋友,你就要改幾次。如果 Jason 有 100 個朋友,你就要改 100 次。
問題二:容易漏改,造成資料不一致
假設你改了第一個 Jason,但忘了改第二個:
| 名稱 | 膚色 | 結婚對象 | 朋友 | 友好程度 |
|---|---|---|---|---|
| David | 深褐色 | Emily | (無) | (無) |
| Emily | 淺褐色 | David | (無) | (無) |
| Jay | 淺褐色 | (無) | David | 高 |
| Jason | 淺褐色 | (無) | Kevin | 中 |
現在資料庫裡同時有 Jay 和 Jason,到底誰是誰?資料變得不一致了。
問題三:刪除資料會牽連其他資料
假設 Jason 和 Kevin 絕交了,你要刪掉這筆朋友關係:
| 名稱 | 膚色 | 結婚對象 | 朋友 | 友好程度 |
|---|---|---|---|---|
| David | 深褐色 | Emily | (無) | (無) |
| Emily | 淺褐色 | David | (無) | (無) |
| Jason | 淺褐色 | (無) | David | 高 |
你只是想刪除「Jason 和 Kevin 的朋友關係」,結果連「Jason 的膚色是淺褐色」這個資訊也一起被刪掉了。
這合理嗎?明明朋友關係跟膚色完全沒有關係,為什麼刪朋友要連膚色一起刪?
分表與關聯查詢的好處
關聯式資料庫的設計原則是:讓重複資料最小化。
怎麼做到?靠的就是「關聯」。
把資料分散在不同的表,每張表各司其職:
- 人物表:只負責儲存人物的基本資料(名稱、膚色)
- 朋友表:只負責儲存朋友關係(誰和誰是朋友、友好程度)
這樣一來,Jason 的膚色只會出現在人物表的一個地方,不管他有多少朋友,都不會重複。
那如果我想知道「Jason 的朋友的膚色」怎麼辦?
這時候就靠「關聯」來串接:
- 先從朋友表查到 Jason 的朋友是 David
- 再用 David 這個名字,去人物表查到他的膚色是深褐色
透過關聯,資料的完整性一樣可以保留,但又避免了重複儲存。這就是「關聯式資料庫」名稱的由來——用關聯取代重複。
分表後的設計
人物表:(每個人只出現一次)
| 名稱 | 膚色 |
|---|---|
| David | 深褐色 |
| Emily | 淺褐色 |
| Jason | 淺褐色 |
朋友表:(只記錄朋友關係)
| 人物 | 朋友 | 友好程度 |
|---|---|---|
| Jason | David | 高 |
| Jason | Kevin | 中 |
分表後的好處
修改資料:
如果 Jason 改名叫 Jay,只需要改人物表的一個地方:
| 名稱 | 膚色 |
|---|---|
| David | 深褐色 |
| Emily | 淺褐色 |
| 淺褐色 |
不管 Jason 有多少朋友,都只需要改這一個地方。
刪除資料:
如果 Jason 和 Kevin 絕交,只需要刪除朋友表的一列:
| 人物 | 朋友 | 友好程度 |
|---|---|---|
| Jason | David | 高 |
Jason 的膚色、名稱等資訊完全不受影響。
需要的時候再關聯查詢
你可能會問:「那我要查 Jason 的朋友的膚色,怎麼辦?」
透過關聯查詢:
- 先從朋友表找到 Jason 的朋友是 David
- 再從人物表找到 David 的膚色是深褐色
不需要把所有資料塞在同一張表,需要的時候再去「關聯」查詢就好。
小結
這篇文章學到的重點:
- 一張表打天下會造成資料重複:當一個人有多筆關係時,他的基本資料會重複出現
- 重複資料的三大問題:
- 修改資料要改很多地方,很麻煩
- 容易漏改,造成資料不一致
- 刪除資料會牽連不相關的資料
- 關聯式資料庫的解決方案:分成多張表,讓重複資料最小化
- 需要的時候再關聯查詢:不需要把所有資料塞在同一張表,透過關聯就能查到需要的資訊
這就是為什麼關聯式資料庫要「關聯」——透過分表和關聯查詢,避免重複資料帶來的各種問題。