SQL Server 数据库中的枚举
Posted
技术标签:
【中文标题】SQL Server 数据库中的枚举【英文标题】:enums in SQL Server database 【发布时间】:2012-02-06 05:34:54 【问题描述】:除了简单地为每个枚举(特别是当每个表中的行数很少时)?我发现了一个article,它建议只为所有枚举创建一个查找表,这种方法受到 cmets 中的一些人的批评,称它违反了引用数据完整性。如果枚举只被一个表使用,使用一些预定义代码然后为它们添加约束(可能使用扩展属性)是一种好习惯吗?
【问题讨论】:
“一个所有枚举的查找表”,又名“一个真正的查找表”,又名“OTLT”,是一种众所周知的 SQL 反模式。你可以谷歌那个。我认为枚举本身是一种数据库反模式,因为它们不容易适应扩展(附加属性)。 【参考方案1】:由于更改代码中的枚举还需要发布应用程序的新版本,所以我根本不使用查找表,而只为相关列添加检查约束。
但是,如果您需要在数据库中存储枚举的本地化名称,那么我会为每个枚举使用一个查找表。
“一个真正的查找表”不会给您带来任何优势。
编辑:如果您需要动态检索枚举值(例如,对于下拉菜单)或需要找出允许的值,那么使用查找表可能更适合您。
【讨论】:
我没有任何本地化要求。检查约束的唯一问题是,仅当查找数据仅在一个表中使用时才能使用,并且表的用户必须查看表的模式定义以查看该列的允许代码和描述 如果您需要使用SELECT
语句查看允许的值,那么查找表可能更适合您。关于“只能在一个表中使用”:我使用SQL Server已经有一段时间了。在 PostgreSQL 中,我将定义一个新的 domain
来封装检查约束并使其可重用。也许在 SQL Server 中也可能出现类似的情况。
即使显示的名称是在代码中生成的,将它们放在表格中也会很有用,因为它们可以在某些报告工具中使用。即使您只是在 sql server manager 中执行查询以检查某些内容,这些名称也很有用。【参考方案2】:
就个人而言,我喜欢为每个枚举定义一个查找表,因为它也是一种文档。如果有人想知道 id 代表什么,他会很容易在表格中找到它。在列约束中查找此信息并不明显。
在表中添加新值也比在约束中容易得多。
如果您创建数据库图表,单个查找表会显得更合乎逻辑。
如果需要(如注释、排序列、某种标志等),除了 id 和文本之外,您还可以向各个查找表添加其他信息。
正如你所说,这对参照完整性更好
但是;如果您使用代码优先方法的 o/r-mapper,使用编程语言提供的枚举感觉很自然。这是因为您不是在设计数据库,而是在设计对象模型。 o/r-mapper 会自动为您创建数据库。
【讨论】:
【参考方案3】:使用同一张表进行多次查找可能会再次困扰您。一个示例是创建索引视图。如果您有多个要显示查找值的字段,这有助于提高性能,但 SQL Server(至少 2005 年)不允许您多次引用同一个表(如果已修复此问题,我真的会想知道如何去做,因为我真的可以在当前应用程序中使用它,只需一个查找表。)。
您的一个查找可能需要一个额外的字段,并且通过使用一个表,您将有很多不必要的空值。使用单独的表索引可以更加灵活。如果一种特定类型的查找需要新字段怎么办? SQL Server 可以很好地处理约束,但如果将其放入同一个表中,则需要稍微复杂一些。
您现在可能没有任何这些问题。我只是没有看到单个表的优势,但是一些应用程序喜欢使用动态方式来生成查找列表,并且不会为每个表创建一个新表。
【讨论】:
以上是关于SQL Server 数据库中的枚举的主要内容,如果未能解决你的问题,请参考以下文章
SQL SERVER 实现多个数据库之间表的联系,利用临时表枚举表中行数据
PCB SQL SERVER 枚举分割函数(枚举值分解函数)