2008-12-12 65 views
45

我的要求的MySQL ENUM類型VS連接表

的表需要保持狀態列。

此列代表5個州中的一個。


初始設計

我想我可以只讓一個整數列和使用數字值表示的狀態。

  • 0 =啓動
  • 1 =運行
  • 2 =墜毀
  • 3 =暫停
  • 4 =停止

因爲我不希望我的應用程序保持從整數映射到字符串描述,我打算把它們放在一個單獨的狀態描述表(依賴於FK關係)。

然後我發現MySQL有一個符合我的要求的ENUM類型。 除了直接依賴於MySQL,使用ENUM類型還有什麼缺陷嗎?

+0

ENUM數據類型從1開始計數,而不是0,如您所示。 – Tomalak 2008-12-12 06:46:47

+1

請參閱:http://dev.mysql.com/doc/refman/5.0/en/enum.html – Tomalak 2008-12-12 06:47:38

回答

81
  • 改變設定在ENUM值的需要ALTER TABLE這可能會導致一個表重組 - 一個令人難以置信的昂貴的操作(如果你只是一個新值添加到的表底重組不會發生ENUM定義,但是如果您刪除一個或更改順序,它將執行表重組)。而在查找表中更改值的集合與INSERT或DELETE一樣簡單。

  • 無法將其他屬性與ENUM中的值相關聯,例如哪些屬性已退役,哪些屬性可以放入用戶界面的下拉列表中。但是,查找表可以包含這些屬性的其他列。

  • 查詢ENUM以獲取不同值列表非常困難,基本上要求您從INFORMATION_SCHEMA查詢數據類型定義,並將列表解析出返回的BLOB。您可以從表中嘗試SELECT DISTINCT status,但只能獲取當前正在使用的狀態值,這可能不是ENUM中的所有值。但是,如果你把值查找表,可以很容易地查詢,排序等

我不是ENUM的大風扇,因爲你可以告訴。 :-)

這同樣適用於CHECK約束,它將列與一組固定值進行簡單比較。儘管MySQL不支持CHECK約束。

+1

感謝Bill對您的提示。有時像ENUM類型的抽象可能看起來簡單而優雅,但是是一個行政時間炸彈。 – ashitaka 2008-12-12 07:05:55

0

表格會更容易國際化。但是數據庫之外的類完全是這樣。枚舉在我看來似乎是尋找問題的一種解決方案 - 或者當你知道數據庫時你使用的是什麼。

7

mysql中的枚舉對於已經解釋過的原因是不利的。
我可以添加以下事實:Enum不確保在服務器端進行任何類型的驗證。如果插入一行的值不在枚舉定義中退出,那麼您將在DB中獲得一個很好的值或NULL值,具體取決於枚舉字段聲明的NULL能力。

我點約tinyints:
- 枚舉限制爲65535個值
- 如果你不需要超過256個值,TINYINT將每一行的空間較小,其行爲更加「predictible」 。

2

如果你的數據庫中有很多數據(更多的數據,那麼你有RAM),你的ENUM值永遠不會改變,我會去與ENUM,而不是連接。它應該更快。
想一想,在連接的情況下,您需要在您的外鍵和索引在另一個表中的主鍵索引。正如Riho所說,看到基準。