MySQL ENUMtypes与连接表

我的要求

一个表需要维护一个状态列。

此列代表5个州之一。

最初的devise

我想我可以使它成为一个整数列,并使用数字值来表示状态。

  • 0 =开始
  • 1 =正在运行
  • 2 =坠毁
  • 3 =暂停
  • 4 =停止

由于我不希望我的应用程序保持从整数到string描述的映射,我打算把它们放在一个单独的状态描述表(依赖于FK关系)。

然后我发现MySQL有一个符合我的要求的ENUMtypes。 除了直接依赖于MySQL,使用ENUMtypes有没有什么缺陷?

  • 更改ENUM中的值集合需要一个ALTER TABLE ,这可能会导致表重组 – 一个令人难以置信的昂贵的操作(如果您只是添加一个新的值到ENUM定义的末尾,表重组不会发生表重组,如果你删除一个,或更改顺序,它执行表重组)。 而在查找表中更改值的集合与INSERT或DELETE一样简单。

  • 没有办法将其他属性与ENUM中的值相关联,比如哪些属性被退役,哪些属性可以放在用户界面的下拉列表中。 但是,查找表可以包含这些属性的其他列。

  • 查询ENUM以获取不同值的列表非常困难,基本上要求您从INFORMATION_SCHEMA查询数据types定义,并将列表从返回的BLOB中parsing出来。 您可以从表中尝试SELECT DISTINCT status ,但只能获取当前正在使用的状态值,可能不是ENUM中的所有值。 但是,如果您将值保存在查找表中,则很容易查询,sorting等。

你可以告诉我,我不是ENUM的忠实粉丝。 🙂

CHECK约束同样适用于将列与一组固定值进行比较。 尽pipeMySQL不支持CHECK约束。

这里是关于枚举速度比较的文章。 也许它提供了一些提示。 恕我直言,它应该被限制在固定的string列表(“是/否”,“儿童/成人”)使用,99%的可能性将来不会改变。

在MySQL中的枚举是已经解释的原因不好。
我可以添加以下事实:Enum不能确保在服务器端进行任何types的validation。 如果插入的行的值不在枚举定义中退出,那么您将在DB中获得一个不错的值或NULL值,具体取决于枚举字段声明的NULL能力。

我关于tinyints的观点:
枚举限制为65535个值
– 如果你不需要256个以上的值,那么tinyint每行将占用更less的空间,而且它的行为更“可预测”。

如果你的数据库中有很多数据(更多的数据,那么你有RAM),你的ENUM值永远不会改变,我会去ENUM,而不是联接。 它应该更快。
想一想,在连接的情况下,你需要在你的外键索引和另一个表中的主键索引。 正如Riho所说,看基准。

一张桌子将更容易国际化。 但是数据库之外的类也是如此。 枚举在我看来似乎是寻找问题的一个解决scheme – 或者当你所知道的只是数据库时你使用的是什么。