SQL Server数据库中的枚举类型

15
是否有更好或更简单的方法来存储枚举(编程语言中的枚举,如C#)在SQL Server数据库中,而不是为每个枚举创建一个查找表(其中包括Id,代码和名称作为列),特别是当这些表中每个都只有很少的行时?我发现一篇 文章 建议为所有枚举创建一个查找表,并且该方法在评论中受到一些人的批评,称其违反了参考数据完整性。如果枚举仅由一个表使用,那么使用一些预定义代码然后为它们添加约束(可以使用扩展属性)是否是一种好的做法?

1
“一个查找表适用于所有枚举”,也称为“The One True Lookup Table”或“OTLT”,是一个众所周知的SQL反模式。你可以在Google上搜索这个。我认为,枚举本身就是数据库反模式,因为它们不容易扩展(添加其他属性)。 - Mike Sherrill 'Cat Recall'
3个回答

18
  1. 个人而言,我喜欢为每个枚举定义一个查找表,因为这也是一种文档。如果有人想知道一个ID代表什么,他可以在表格中轻松找到。在列约束中寻找此信息并不明显。

  2. 在表格中添加新值比在约束中更容易。

  3. 如果您创建了数据库图表,则单独的查找表看起来更加合乎逻辑。

  4. 如果需要,您可以在单个查找表中添加除ID和文本之外的其他信息(例如注释、排序列、某种标志等)。

  5. 正如您所说,这对于符合参照完整性要求更好。

但是,如果您使用基于代码的o/r映射器,则使用编程语言提供的枚举会感觉很自然。这是因为您正在设计对象模型而不是数据库。o/r-mapper会自动为您创建数据库。


0

由于更改代码中的枚举也需要发布应用程序的新版本,因此我建议不要使用查找表,而是仅向相关列添加检查约束。

但是,如果您需要在数据库中存储枚举的本地化名称,则应为每个枚举使用一个查找表。

“唯一的查找表”不会给您带来任何优势。

编辑:如果您需要动态检索枚举值(例如下拉列表)或需要找出允许哪些值,则使用查找表可能更适合您。


我没有任何本地化要求。唯一的问题是检查约束只能在查找数据仅用于一个表的情况下使用,而且表的用户必须查看表的模式定义,以查看该列的允许代码和描述。 - RKP
如果您需要使用SELECT语句查看允许的值,则查找表可能更适合您。关于“只能在一个表中使用”的问题:我已经有一段时间没有使用SQL Server了。在PostgreSQL中,我会定义一个新的“域”,封装检查约束并使其可重用。也许在SQL Server中也可以实现类似的功能。 - user330315
即使显示的名称是在代码中生成的,将它们放在表格中也很有用,因为它们可以在某些报告工具中使用。即使您只是在 SQL Server 管理器中执行查询以检查某些内容,这些名称也可能会有用。 - Olivier Jacot-Descombes

0

在多个查找中使用相同的表可能会让你后悔。一个例子是创建索引视图。如果您有几个字段需要显示查找值,则可以通过此方法提高性能,但 SQL Server(至少2005)不允许您多次引用同一张表(如果已经修复了这个问题,我真的很想知道如何解决,因为我目前的应用程序需要使用单个查找表)。

您的某个查找可能需要额外的字段,而使用一个表,您将拥有大量不必要的空值。使用单独的表进行索引可以更加灵活。如果新字段需要针对特定类型的查找,则 SQL Server 可以很好地处理约束,但是当放入同一张表中时,需要更多的复杂性。

您现在可能没有任何这些问题。我只是认为单个表没有优势,但有些应用程序喜欢以动态方式生成查找列表,并且不会为每个列表创建新表。


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