在有與沒有之間--為什麼設計資料庫欄位時不建議用布林值

最近「在有與沒有之間」這句話紅透半邊天,成為許多人茶餘飯後揶揄的話題。

雖然「在有與沒有之間」乍聽之下很不可思議,但是這也反應了現實世界的不確定性。

我們這篇文章就用「在有與沒有之間」來討論為什麼設計資料庫欄位時,不建議用布林值的data type。

根據小弟多年接案的經驗,若要設計符合現實世界的系統時,一定要考慮到現實世界不確定性。


先從戰男女開始

以前很常看到資料庫的性別欄位,用 True 或 False 來表示。

這類的資料庫常常把男性塞入 True 值,女性塞入 False。

會有這樣子的設計是因為布林值只有 True 和 False,而剛好男女是兩個性別,可以對應布林值。

但這很容易就引發了論戰,為什麼男性就是「對的」,女性就是「錯的」?

如果反過來,又會被爭論,為什麼女性就是「對的」,男性就是「錯的」?

性別議題其實是很嚴重的問題,或許生在台灣的我們覺得還好,可是在美國如果有職場上的性別歧視,那一定就等著被告上法院了。

因此,性別實在不適合用 True 或 False 來表示。

現在多了跨性別者的選項

傳統上只是男女的二分法,用布林值來實現是可行的。

但是隨著人權的發展以及醫學的進步,大家開始認知到跨性別者的存在。

性別欄的部分就必須多了一個選項,因此布林值的二分法就完全不能使用了。

布林值只有 True 和 False,沒有「在 True 與 False之間」這個值。

所以在設計資料庫的性別欄位時,已經不能使布林值了。

真實世界的「在有與沒有之間」

許多系統在一開始設計的時候,可能都會只使用布林值來表示兩種狀態。

我們來舉個例子說明。

某公司的公文系統,在送出公文之後,會在系統上看到該公文的兩種狀態:完成 和 未完成。

完成和未完成這兩種狀態,一開始軟體工程師在設計系統時,就用了布林值來做欄位。

幾年後,老闆突然抱怨說,系統上只能看到完成和未完成,根本不知道該職員是否已經收到那份公文,開始進行。

因此要求IT人員在公文系統裡新增一個「處理中」的狀態。

哇這下子就慘了,原本欄位只能塞布林值,可是現在多出了第三種狀態,就塞不進去該欄位了。

要解決這個情況,第一個方法是把資料表上,再加上一個欄位,再顯示進行中的狀態

第二個方法就是把原本布林值的欄位,改成其他的data type。

兩種方法都有可能讓整個系統掛掉,費很多功能來重寫重構。

較佳的欄位設計

注意我用的詞是「較佳」的欄位設計,不是絕對。世上沒有什麼系統是絕對的。

較佳的設計方式,應該把布林值的欄位改成存 int 的data type。

另外再有一張表,存該 int 所代表的內容。

以性別為例,開一張 gender 表,男性存0,女性存1,跨性別存2

然後在主會員資料表中的 gender 欄位,就存 0, 1, 2。

未來如果有第四性別的產生就可以存入4,

如此一來,系統就不用大改了。

同樣的方式,剛剛的公文系統也可以開一張 status 表

未完成存0,處理中存1,完成存2

然在公文資料表中的 status 欄位,就存0, 1 ,2。

未來如果老闆要再加入其他的狀態,如「會簽其他科室」,就可以存3

如此一來,就不會因為改系統,導致全公司的公文系統都不能用了

注意,有些資料庫如MySQL是把布林值視為TINYINT,這要小心

結語

  1. 用布林值來存資料,可能導致某些人不開心。
  2. 用布林值來存資料,容易讓系統缺乏擴充性。
  3. 有人或許會爭論,用布林值是比較快速的作法,但是要想想擴充性啊。

如果這篇文章有幫助到你,歡迎在下方disqus留言版點擊愛心推荐哦!有任何問題請留言討論!
也歡迎把大魔術熊貓工程師的文章連結分享出去哦!!