前面的文章我們討論關係類型時,都在問「最多」:
- 一個會員最多可以有幾支電話?
- 一支電話最多可以被幾個會員持有?
但有沒有想過:最少呢?可不可以完全沒有?
例如一個會員可不可以完全沒有電話?一個人可不可以沒有配偶?
這篇文章會介紹資料庫中的「空值」(NULL),以及它的特殊性質。
一對多關係:沒有資料不是問題
先看一對多的情況。
一個會員可不可以完全沒有電話?當然可以。
如果會員沒有電話,會發生什麼事?
會員表單:
| 會員 ID | 會員名稱 |
|---|---|
| U001 | David |
| U002 | Emily |
會員電話表單:
| 電話 | 會員 ID |
|---|---|
| 0912-345-678 | U001 |
| 0922-111-222 | U001 |
Emily(U002)沒有電話,所以會員電話表單裡完全沒有她的資料。這樣就好了,沒什麼問題。
一對多關係中,「沒有」就是「那張表單裡沒有對應的資料列」,很單純。
一對一關係:沒有資料要填什麼?
但一對一關係就不一樣了。
假設我們有一個「人物表單」,記錄每個人和他的配偶:
| 人物 | 配偶 |
|---|---|
| David | Emily |
| Emily | David |
| Frank | ? |
David 和 Emily 結婚了,所以他們互相是對方的配偶。
但 Frank 未婚,他的「配偶」欄位要填什麼?
錯誤做法:新增一個叫「沒有人」的資料
你可能會想:那我新增一個人叫「沒有人」,讓 Frank 的配偶指向「沒有人」。
| 人物 | 配偶 |
|---|---|
| David | Emily |
| Emily | David |
| Frank | 沒有人 |
| 沒有人 | Frank |
看起來好像可以?
但問題來了:如果又有一個人 Kevin 也未婚呢?
| 人物 | 配偶 |
|---|---|
| David | Emily |
| Emily | David |
| Frank | 沒有人 |
| Kevin | 沒有人 |
| 沒有人 | ? |
「沒有人」重婚了!
還記得我們說過,一對一關係的「配偶」欄位應該加上 UNIQUE 限制,確保每個值只出現一次。
但現在「沒有人」出現了兩次,違反了 UNIQUE 限制。
所以這個做法行不通。
正確做法:使用 NULL
資料庫有一個特殊的值叫做 NULL,代表「空值」或「沒有資料」。
| 人物 | 配偶 |
|---|---|
| David | Emily |
| Emily | David |
| Frank | NULL |
| Kevin | NULL |
Frank 和 Kevin 的配偶欄位都填 NULL,表示他們沒有配偶。
NULL 的特殊性質
NULL 有一個很特別的性質:
每一個 NULL 都被視為完全不同的值。
這是什麼意思?讓我們比較一下「沒有人」和 NULL 的差異。
用「沒有人」的情況
| 人物 | 配偶 |
|---|---|
| Frank | 沒有人 |
| Kevin | 沒有人 |
「沒有人」是一個具體的值。Frank 填的「沒有人」和 Kevin 填的「沒有人」是同一個值。
所以如果「配偶」欄位有 UNIQUE 限制,這就違反了——同一個值「沒有人」出現了兩次。
用 NULL 的情況
| 人物 | 配偶 |
|---|---|
| Frank | NULL |
| Kevin | NULL |
NULL 不是一個具體的值,它代表「沒有資料」。
Frank 的 NULL 和 Kevin 的 NULL 是不同的 NULL。每次出現的 NULL 都是獨立的,彼此之間不相等。
所以即使「配偶」欄位有 UNIQUE 限制,兩個人都填 NULL 也不會違反限制。
用比喻來理解
你可以這樣想:
- 「沒有人」就像是一個真實存在的人,名字叫「沒有人」。如果兩個人都跟「沒有人」結婚,那「沒有人」就重婚了。
- NULL 則是「這格沒有填資料」。Frank 沒填,Kevin 也沒填,但這是兩個人各自「沒填」,不是他們填了同樣的東西。
這就是為什麼 NULL 可以解決「沒有配偶」的問題,而「沒有人」不行。
NULL 的模糊地帶
NULL 解決了「沒有資料」的問題,但它也帶來一個模糊地帶。
當你看到 Frank 的配偶是 NULL,這代表什麼意思?
可能性一:Frank 確實未婚
他沒有配偶,所以填 NULL。
可能性二:Frank 已婚,但我們不知道配偶是誰
也許他不願意告訴我們,也許資料漏填了。我們知道他有配偶,但不知道是誰,所以填 NULL。
這兩種情況都會填 NULL,但意義完全不同。
如何區分「沒有」和「不知道」?
如果你需要區分這兩種情況,可以另外加一個欄位。
例如加一個「已婚」欄位:
| 人物 | 配偶 | 已婚 |
|---|---|---|
| David | Emily | true |
| Emily | David | true |
| Frank | NULL | false |
| Kevin | NULL | true |
現在我們可以區分了:
- Frank:配偶是 NULL,已婚是 false → 他確實未婚
- Kevin:配偶是 NULL,已婚是 true → 他已婚,但我們不知道配偶是誰
這樣就能清楚表達「確定沒有」和「有但不知道是誰」的差別。
NULL 重點整理
這篇文章介紹了 NULL 的概念:
- 問題:一對一關係中,如果沒有對應的資料,欄位要填什麼?
- 錯誤做法:新增一個「沒有人」的資料 → 會違反 UNIQUE 限制
- 正確做法:使用 NULL
- NULL 的特殊性質:每個 NULL 都被視為不同的值,不會違反 UNIQUE
- NULL 的模糊地帶:NULL 可能代表「沒有」,也可能代表「不知道」
- 區分方法:如果需要區分,可以另外加一個欄位(例如「已婚」)
NULL 是資料庫中很重要的概念,後續在寫查詢語法時也會經常遇到它。