Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

資料庫架構設計入門:用 FOREIGN KEY 建立表單之間的關聯

最後更新:2026年1月12日資料庫

前面我們介紹了主鍵(Primary Key),它幫助我們唯一識別每一筆資料。

有了主鍵之後,我們終於可以介紹另一個很重要的限制:外部鍵(Foreign Key)。

什麼是外部鍵?為什麼需要它?我們來看一個例子。

為什麼需要外部鍵

假設我們有一個「結婚表」:

人物結婚對象
DavidEmily
EmilyDavid
FrankNULL
GraceHenry
結婚對象Emily
結婚對象David
結婚對象NULL
結婚對象Henry

我們來檢查每一筆資料的「結婚對象」是否合理:

第一筆:David 的結婚對象是 Emily

Emily 有出現在人物欄位嗎?有,第二筆的人物就是 Emily。所以這筆資料沒問題 ✓

第二筆:Emily 的結婚對象是 David

David 有出現在人物欄位嗎?有,第一筆的人物就是 David。所以這筆資料沒問題 ✓

第三筆:Frank 的結婚對象是 NULL

NULL 代表「沒有值」,表示 Frank 沒有結婚。這也沒問題 ✓

第四筆:Grace 的結婚對象是 Henry

Henry 有出現在人物欄位嗎?我們來看看:David、Emily、Frank、Grace… 沒有 Henry!

Grace 說她的結婚對象是 Henry,但 Henry 根本不在這張表的人物欄位裡。這代表 Grace 的結婚對象是一個「不存在的人」。

這筆資料是有問題的。我們不應該允許這種情況發生。

那怎麼辦?

我們希望資料庫能幫我們擋掉這種情況:如果人物欄位裡沒有這個人,結婚對象就不能填這個人。

這種「一個欄位的值必須參考另一個欄位」的限制,就叫做外部鍵(Foreign Key)。

設定外部鍵之後,資料庫會自動幫你檢查:如果你試著填入一個不存在的值,資料庫就會拒絕寫入,不讓這筆資料進到資料庫裡。

設定外部鍵

當你設定外部鍵的時候,一定要說明:這個欄位要參考誰?

這個「參考的對象」叫做 Reference(參考)。

以結婚表為例:

人物(PK)結婚對象(FK)
DavidEmily
EmilyDavid
FrankNULL
GraceHenry
結婚對象(FK)Emily
結婚對象(FK)David
結婚對象(FK)NULL
結婚對象(FK)Henry

這裡的「結婚對象」欄位設定了外部鍵,它的 Reference 是「人物」欄位。

這表示:

  • 結婚對象填的值,必須是人物欄位裡出現過的值
  • 如果人物欄位裡沒有 Henry,那結婚對象就不能填 Henry

違反外部鍵限制會怎樣

如果你試著在「結婚對象」填入一個人物欄位裡不存在的人(像 Henry),會發生什麼事?

我們來看一下這個情況:

人物(PK)結婚對象(FK)
DavidEmily
EmilyDavid
FrankNULL
GraceHenry
結婚對象(FK)Emily
結婚對象(FK)David
結婚對象(FK)NULL
結婚對象(FK)Henry

Grace 的結婚對象是 Henry,但人物欄位裡沒有 Henry。這筆資料違反了外部鍵的限制。

當你試著寫入這筆資料時,資料庫會怎麼處理?

有兩種常見的處理方式:

  1. 拒絕寫入:資料庫直接擋掉這筆資料,不讓你寫進去。你會看到一個錯誤訊息,告訴你「違反外部鍵限制」。
  2. 設為空值:資料庫讓你寫入,但把結婚對象自動改成 NULL。

大多數情況下是第一種:直接擋掉。

為什麼?因為如果資料庫自動把值改成 NULL,你可能不知道原本填的值有問題。直接報錯可以讓你馬上發現問題,確保資料的一致性。

外部鍵通常搭配 NOT NULL

在結婚表的例子裡,結婚對象可以是 NULL(像 Frank 沒有結婚)。這是合理的,因為不是每個人都有結婚。

但有些情況下,外部鍵欄位不應該是空值。

例如,假設你有一張「訂單表」:

訂單 ID(PK)商品名稱所屬會員(FK)
1鍵盤U001
2滑鼠U002
3螢幕NULL
商品名稱鍵盤
所屬會員(FK)U001
商品名稱滑鼠
所屬會員(FK)U002
商品名稱螢幕
所屬會員(FK)NULL

第三筆訂單的「所屬會員」是 NULL。這代表什麼?

這筆訂單是誰下的?不知道。沒有會員,怎麼出貨?怎麼收款?這筆資料根本沒有意義。

所以在訂單表裡,「所屬會員」應該要加上 NOT NULL 限制,確保每筆訂單都有對應的會員。

要不要加上 NOT NULL,取決於這個欄位在業務邏輯上是否允許空值:

  • 結婚對象:可以是 NULL(沒結婚是正常的)
  • 訂單的所屬會員:不應該是 NULL(每筆訂單一定要有人下單)

外部鍵通常指向主鍵

外部鍵的 Reference(參考對象)可以是任何欄位嗎?

技術上可以,但絕大多數情況下,外部鍵都會指向主鍵(Primary Key)。

為什麼?

回想一下結婚表的例子:

人物(PK)結婚對象(FK)
DavidEmily
EmilyDavid
結婚對象(FK)Emily
結婚對象(FK)David

結婚對象的 Reference 是「人物」欄位,而人物欄位是這張表的主鍵。

主鍵有三個條件:不能重複、不應該改變、不能是空值。

如果外部鍵指向的欄位不是主鍵,可能會發生什麼事?

  • 如果那個欄位會重複:結婚對象填 David,但有兩個 David,到底是指哪一個?
  • 如果那個欄位會改變:結婚對象填 David,結果 David 改名叫 Kevin,關聯就斷掉了
  • 如果那個欄位是空值:結婚對象填的值根本不存在

這跟我們在 PRIMARY KEY 那篇說的「用姓名關聯」的問題一模一樣。

那正確的做法是什麼?

如果人物欄位不是主鍵,我們應該另外建立一個 ID 欄位當主鍵,然後讓結婚對象指向這個 ID:

人物 ID(PK)人物姓名結婚對象(FK)
1David2
2Emily1
3FrankNULL
人物姓名David
結婚對象(FK)2
人物姓名Emily
結婚對象(FK)1
人物姓名Frank
結婚對象(FK)NULL

現在結婚對象填的是 ID,不是姓名。就算 David 改名叫 Kevin,結婚對象填的還是 2,關聯不會斷掉。

所以,外部鍵應該指向主鍵,才能確保外部鍵真正指向一筆特定的、不會變的資料。

FOREIGN KEY 重點整理

  1. 什麼是外部鍵:一個欄位的值必須參考另一個表單的欄位
  2. 為什麼需要:確保關聯的資料真的存在,避免指向不存在的資料
  3. Reference:設定外部鍵時,必須指定參考的對象是哪個表單的哪個欄位
  4. 違反限制:通常會拒絕寫入,確保資料一致性
  5. 搭配 NOT NULL:大多數情況下,外部鍵欄位不應該是空值
  6. 指向主鍵:外部鍵通常指向另一張表的主鍵,確保指向特定的資料

到目前為止,我們學了四種欄位限制:

  • UNIQUE:確保欄位的值不重複
  • NOT NULL:確保欄位一定要有值
  • PRIMARY KEY:確保可以唯一識別每一筆資料(包含 UNIQUE + NOT NULL)
  • FOREIGN KEY:確保欄位的值必須參考另一個表單的欄位
目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

資料庫

目錄

  • 為什麼需要外部鍵
  • 設定外部鍵
  • 違反外部鍵限制會怎樣
  • 外部鍵通常搭配 NOT NULL
  • 外部鍵通常指向主鍵
  • FOREIGN KEY 重點整理