枚举存储在数据库字段中

时间:2009-06-18 20:36:31

标签: database enums

最好将枚举或枚举名称存储在数据库表字段中吗?

例如,我应该将'TJLeft'存储为字符串或它在数据库中的等效值吗?

Public Enum TextJustification
  TJLeft
  TJCenter
  TJRight
End Enum

我目前正倾向于这个名字,因为有些人可能会稍后出现,并明确指定一个不同的值。

编辑 -

有些枚举是在我的控制之下,但有些是来自第三方。

8 个答案:

答案 0 :(得分:5)

存储数值的另一个原因是,如果您在枚举中使用[Flags]属性,则可能需要允许多个枚举值。比方说,例如,你想让别人选择一周中哪些日子可用于某事......

[Flags] 
public enum WeekDays     
{
   Monday=1,
   Tuesday=2,
   Wednesday=4,
   Thursday=8,
   Friday=16
}

在这种情况下,您可以将数值存储在db中以获取任何值的组合(例如,3 ==星期一和星期二)

答案 1 :(得分:2)

对于您自己的枚举,请使用数值,原因很简单:它允许enum功能的每个部分,开箱即用,没有麻烦。唯一需要注意的是,在enum定义中,每个成员都必须明确地给出一个数值,这可以从不更改(或者,至少,不是在您发布第一个版本之后) )。我总是在枚举中添加一个突出的注释,这些注释会持久存储到数据库中,因此人们不会更改常量。

以下是数值优于字符串标识符的一些原因:

  • 这是表示价值的最简单方法
  • 数据库搜索/排序更快
  • 降低数据库存储成本(这可能是某些应用程序的严重问题)
  • 您可以将[Flags]添加到enum,而不会破坏您的代码和/或现有数据
  • 对于存储在字符串字段中的[Flags]
    • 数据标准化不足
    • 在进行匹配时可能会产生误报异常(即,如果您有成员“Sales”和“RetailSales”,则仅对子行搜索“Sales”将匹配任一类型)。这必须通过在字边界上使用正则表达式(使用数据库挑剔,速度慢)或限制枚举本身来限制,这是非标准的,容易出错,并且很难调试。
  • 对于字符串字段([Flags]或不是enum),如果对数据库进行模糊处理,则必须处理此字段,这会极大地影响搜索/排序代码时的能力和效率,如前一点所述
  • 您可以在不破坏数据库代码和/或现有客户端数据的情况下重命名任何成员。
  • 所需的线上数据传输空间/时间较少

只有两种情况,在数据库中使用成员名称可能是一个优势:

  • 如果您手动进行大量数据编辑......但是谁这样做?如果你是的话,你很可能不会使用enum
  • 第三方枚举,它们可能不那么勤奋以至于维持数值常量。但我不得不说,任何发布一个体面的API的人都绝对有足够的智慧来保持[Flags]值不变。 (标识符必须保持不变,因为更改它们会破坏现有代码。)

在查询表上,我强烈反对,因为它们是维护噩梦的单向子弹列车:

  • 添加enum功能需要使用联结表,这意味着更复杂的查询(现有的查询需要重写),并增加了复杂性。现有客户数据怎么样?
  • 如果标识符存储在数据表中,那么首先有一个查找表是什么意思?
  • 如果数值存储在数据表中,则无法获得任何内容,因为您仍需要从查找表中查找标识符。为了简化操作,您可以为每个表创建一个视图...其中包含[Flags]值。然后我们甚至不考虑{{1}}枚举。
  • 在数据库和代码之间引入任何类型的同步只是在寻找麻烦。现有客户数据怎么样?

答案 2 :(得分:1)

我总是使用由字段

组成的查找表
  • OID int(pk)作为数值
  • ProgID varchar(唯一)作为C#中的值标识符(即const名称或枚举符号)
  • ID nvarchar作为显示值(UI)

dbscript让我从查找表中生成C#代码,因此我的代码始终与数据库同步。

答案 3 :(得分:0)

存储ID(值)和varchar名称;这允许您以任一方式查询。如果您的ID(值)稍后可能不同步,则搜索名称是合理的。

答案 4 :(得分:0)

最好使用整数表示...如果您以后必须更改枚举(添加更多值等),您可以显式将整数值分配给Enum值,以便您的代码中的Enum表示仍然与您匹配拥有数据库。

答案 5 :(得分:0)

这取决于性能与可读性的重要程度。数据库可以比字符串更容易地索引数值,这意味着您可以在不使用尽可能多的内存的情况下获得更好的性能。它还可以减少线路上的数据量。另一方面,当您查看数据库中的数值时,您必须引用要翻译的代码文件,这可能很烦人。

在大多数情况下,我建议使用该值,但您需要确保明确设置这些值,以便在将来添加值时不会移动引用。

答案 6 :(得分:0)

通常取决于很多事情:

你想按照枚举的自然顺序排序吗?使用数值。 您是否使用低级工具直接在数据库中工作?使用名称。 你有大量的数据和性能是一个问题吗?使用数字

对我来说,最重要的问题是大部分时间的可维护性:

如果您的枚举将来发生变化,名称将正确匹配失败和大声失败。对于数字,有些人可以添加枚举实例,更改所有枚举的所有数字,因此您必须更新使用枚举的所有表。几乎没有办法知道你是否错过了一张桌子。

答案 7 :(得分:0)

如果您尝试获取存储在数据库中的枚举值,请尝试使用

EnumValue = DirectCast([Enum].Parse(GetType(TextJustification), reader.Item("put_field_name_here").ToString), TextJustification)

告诉我它是否适合你