枚举 vs 参考表 vs 查找类

14

在为约会网站设计MySQL数据库时,我遇到了如何存储引用数据的疑问。当前数据库有33张表,有近32个不同的字段需要进行引用。我们还必须考虑到其中许多元素需要翻译。

在阅读了几种意见之后,我几乎排除了使用枚举,比如:

CREATE TABLE profile (
  'user_id' INT NOT NULL,
 ...
  'relationship_status' ENUM('Single','Married') NOT NULL,
 ... 
);

通常我会使用一个参考表,例如:

CREATE TABLE profile (
  'user_id' INT NOT NULL,
 ...
  'relationship_status_id' INT NOT NULL, 
 ... 
);

CREATE TABLE relationship_status (
  'id' INT NOT NULL,
  'name' VARCHAR(45) NOT NULL,
  PRIMARY KEY ('id') 
);

但是如果创建32个表可能会过度设计,所以我正在考虑像这样使用PHP编写代码:


class RelationshipStatusLookUp{
  const SINGLE = 1;
  const MARRIED = 2;

  public static function getLabel($status){
      if($status == self::SINGLE)
         return 'Single';
      if($status == self::MARRIED)
         return 'Married';
      return false;
  }
}

您认为呢?因为我猜这可能会提高查询的性能,并使整个站点的开发更加容易。

谢谢。


1
我想说的是,如果您决定在 PHP 代码之外使用该数据,则选项三并不会很有帮助。我建议选择选项二,而且我真的认为性能不会受到影响,因为引用表的存在。 - Ascherer
2
我们还必须考虑到许多这些元素需要翻译。不要尝试在数据库层面处理翻译。你应该在你的PHP中处理它。 - augustknight
另外,如果您计划实现ORM,一些ORM(如Doctrine)甚至不支持枚举类型。 - Ascherer
这是一个关于数据库枚举类型的问题,以下是之前类似问题的一些好回答:http://stackoverflow.com/questions/336846/database-enums-pros-and-cons - Mark Baker
3个回答

12

在我看来,远离ENUM肯定是个好主意:为什么ENUM很糟糕。从技术上讲,查找表应该是首选解决方案,尽管对于简单的值,PHP类也可以工作。您需要小心处理此问题,原因与ENUM相同; 如果集合中的值增长,维护可能变得困难。(例如“共同生活”,“离婚”,“民事伴侣关系”,“丧偶”等)。使用PHP类查询值列表也不是易事;它可以使用反射来实现,但不像简单的MySQL SELECT那样容易。这可能是其中之一,在这种情况下,我不会担心性能,除非它成为一个问题。首先使用最佳解决方案进行编码/应用程序,然后如果需要,再进行优化。


是的,我两天前读了它,它帮助我放弃了枚举,但我将其添加到问题中,因为这是另一个要考虑的选项。 - Puigcerber
@Puigcerber 我认为枚举值是值得考虑的。在某些边缘情况下,它们可能是一个不错的选择。只要你理解使用它们的缺点... - liquorvicar
我在考虑也许可以将其与性别和其他固定数据一起使用,但我想我会为所有内容使用参考表。如果参考不受强制执行,您是否允许父表中的NULL,还是最好在引用表中使用0值? - Puigcerber

5

枚举字段存在一些问题:

  • Once they're set, they can't easily be changed

    'relationship_status' ENUM('Single','Married') NOT NULL,
    

    would need 'Civil Partnership' adding in this country nowadays

  • You can't easily create a dropdown list of options from the enum lists

然而,数据库中的数据可能会受到引用完整性约束的限制,因此使用对参考表的外键链接可以在不使用枚举的约束的情况下提供验证的程度。维护类中的选项需要对代码进行更改以添加新选项到数据中,这可能会增加工作量,具体取决于您的发布程序,并且无法防止插入错误数据到数据库。个人而言,我会选择使用参考表。

2
首先,在Relationship_status表中,您不需要使用id和relationship_status_id。
个人建议,除非您需要关联更多数据而不仅仅是人的关系状态名称(或者如果您预见未来需要扩展此功能),否则我会使用枚举。如果它以易于阅读的语言呈现,那么在查看数据库时将更加容易,而不是必须针对第二个表进行查询。
考虑性能时,通过唯一ID查询表确实更快,但您必须跟踪该关系,并且始终会连接多个表以获取相同的数据。如果枚举解决方案最终变慢,我认为即使使用大型数据集,人脑也无法感知到差异。

很抱歉,relationship_status_id 是复制粘贴时出现的错误。 - Puigcerber
3
在参照表上进行连接并不是非常困难的事情,而且数据库并不应该以易于阅读的语言呈现,它应该以提供最佳结构、有效性和性能的方式来构建,而枚举并不能提供这些。 - Ascherer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接