Database 数据库字段中的枚举存储

Database 数据库字段中的枚举存储,database,enums,Database,Enums,最好将枚举值或枚举名称存储在数据库表字段中 例如,我应该将“TJLeft”存储为字符串还是将其等效值存储在数据库中 Public Enum TextJustification TJLeft TJCenter TJRight End Enum 我目前倾向于使用这个名称,因为有些名称可能会在以后出现,并显式地指定不同的值 编辑- 有些枚举由我控制,但有些来自第三方。存储ID(值)和varchar名称;这使您可以通过任何一种方式进行查询。如果您的ID(值)以后可能会不同步,则搜索名称是合理

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

例如,我应该将“TJLeft”存储为字符串还是将其等效值存储在数据库中

Public Enum TextJustification
  TJLeft
  TJCenter
  TJRight
End Enum
我目前倾向于使用这个名称,因为有些名称可能会在以后出现,并显式地指定不同的值

编辑-


有些枚举由我控制,但有些来自第三方。

存储ID(值)和varchar名称;这使您可以通过任何一种方式进行查询。如果您的ID(值)以后可能会不同步,则搜索名称是合理的。

最好使用整数表示法。。。如果以后必须更改枚举(添加更多值等),可以显式地将整数值指定给枚举值,以便代码中的枚举表示形式仍与数据库中的枚举表示形式相匹配。

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


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

通常这取决于许多因素:

是否要按枚举的自然顺序排序?使用数字值。 您是否使用低级工具直接在数据库中工作?使用名称。 您是否拥有大量的数据,而性能是一个问题?使用号码

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


如果您的枚举在将来发生更改,则名称将要么正确匹配,要么严重失败。使用数字,可以添加一个枚举实例,更改所有枚举的所有数字,因此必须更新使用枚举的所有表。几乎没有办法知道是否遗漏了一个表。

存储数值的另一个原因是,如果您希望允许多个枚举值,则在枚举中使用[Flags]属性。比如说,你想让某人选择一周中哪几天可以做某事

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

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

我始终使用由字段组成的查找表

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

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

对于您自己的枚举,使用数值,原因很简单:它允许使用
enum
功能的每一部分,开箱即用,没有任何麻烦。唯一需要注意的是,在
enum
定义中,必须显式地为每个成员指定一个数值,该数值可以永远不会更改(或者至少在您发布第一个版本后不会更改)。我总是在枚举中添加一条显著的注释,并将其持久化到数据库中,这样人们就不会去更改常量

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

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

  • 如果您正在手动进行大量数据编辑。。。但谁会这么做?如果是,很有可能您不会使用
    enum
  • 第三方枚举,他们可能不太注意维护数值常量。但我必须说,任何发布一个编写得体的API的人都可能非常聪明,能够保持
    enum
    值不变。(标识符必须保持不变,因为更改它们会破坏现有代码。)
在查找表上,我强烈反对,因为它们是维护噩梦的单向子弹列车:

  • 添加
    [Flags]
    功能需要使用连接表,这意味着更复杂的查询(现有查询需要重写)和增加的复杂性。现有的客户端数据呢
  • 如果标识符存储在数据表中,那么首先使用查找表有什么意义
  • 如果数字值存储在数据表中,那么您将一无所获,因为您仍然需要从查找表中查找标识符。使之容易
    EnumValue = DirectCast([Enum].Parse(GetType(TextJustification), reader.Item("put_field_name_here").ToString), TextJustification)