将枚举值存储在数据库中

Kam*_*yar 21 sql-server enums database-design

仅供参考:我明确指的是SQL Server 2000-8和C#.因此,像MySql这样具有枚举支持的DBMS不是我的问题的主题.

我知道这个问题在SO中被多次询问过.但是,我仍然在答案中看到,采用不同的方法在db中存储枚举值.

  1. 将枚举保存为db中的int并在代码中提取枚举值(或使用反射的枚举描述属性):
    这是我通常使用的方法.问题是当我尝试从SSMS中的数据库查询时,检索到的数据很难理解.

  2. 将枚举保存为db中的字符串(varchar)并在代码中强制转换为int.
    实际上,这可能是最好的解决方案.但是(不要笑!)它感觉不对.我不确定这个缺点.(除了db中通常可以接受的更多空间之外)还有其他任何反对这种方法的方法吗?

  3. 在db中有一个单独的表,它与代码的枚举定义同步,并在主表和枚举表之间建立外键关系.
    问题是稍后应该添加另一个枚举值,代码和数据库都需要更新.此外,可能会有拼写错误!

所以一般来说,当我们在第二个解决方案中接受db的开销时,在db中存储枚举值的最佳方法是什么?对此有一个明确的设计模式规则吗?
谢谢.

vcs*_*nes 18

没有确定的设计规则(我知道),但我更喜欢方法#1.

  1. 是我喜欢的方法.它很简单,枚举通常很紧凑,我开始记得数字的含义.
  2. 它更具可读性,但在您想要的时候可能会妨碍重构或重命名枚举值.你失去了一些代码自由.突然之间你需要让DBA参与进来(取决于你工作的地点/方式)只是为了改变一个枚举值,或者受到它的影响.解析枚举也会对性能产生一些影响,因为像Locale这样的东西会起作用,但可能会忽略不计.
  3. 这解决了什么问题?除非您想要添加连接的开销,否则在某个表中仍然存在不可读的数字.但有时候,这也是正确的答案,具体取决于数据的使用方式.

编辑:Chris在评论中提出了一个很好的观点:如果您确实按照数值方法进行操作,则应明确指定值,以便您也可以重新排序它们.例如:

public enum Foo
{
     Bar = 1,
     Baz = 2,
     Cat = 9,
     //Etc...
}
Run Code Online (Sandbox Code Playgroud)

  • @Chris:然后明确定义值. (4认同)
  • 如果你重新订购你的枚举,1号会造成麻烦. (2认同)

gbn*_*gbn 6

我之前见过的一个想法是你的选择3或多或少

  • 数据库中的表(用于外键等)
  • 客户端代码中匹配的Enum
  • 启动检查(通过数据库调用)以确保它们匹配

数据库表表可以具有触发器或检查约束,以降低更改的风险.它不应该具有任何写入权限,因为数据与客户端代码版本相关联,但它增加了一个安全因素,以防DBA bollixes up

如果您有其他客户端读取代码(这是非常常见的),那么数据库就有完整的数据.

  • @Kamyar:加入数据库引擎的开销?你在开玩笑吧? (5认同)
  • 是不是会造成开销?在许多文章中,建议使用较少的连接.(只要它不会影响正常化*非常糟糕*)例如:http://www.sql-server-performance.com/2007/database-design/ (2认同)