2008-12-12 50 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所说,看到基准。