问题描述
|
仅供参考:我明确表示sql Server 2000-8和C#。因此,具有枚举支持(例如MysqL)的DBMS并不是我的问题。
我知道这个问题已经在SO中多次问过。但是,我仍然在回答中看到采用不同的方法将枚举值存储在db中。
在数据库中将枚举另存为int并在代码中提取枚举值(或使用反射的枚举描述属性):
这是我通常使用的方法。问题是当我尝试从SSMS中的数据库查询时,检索到的数据很难理解。
在数据库中将枚举另存为字符串(varchar),然后在代码中转换回int。
实际上,这可能是最好的解决方案。但是(别笑!)感觉不对。我不确定缺点。 (除了通常可以接受的db中更多的空间),还有其他反对这种方法的事情吗?
在db中有一个单独的表,该表与代码的枚举定义同步,并在主表和枚举表之间建立外键关系。
问题是,以后应添加另一个枚举值时,代码和db都需要更新。另外,可能会有错别字,可能会很痛苦!
因此,通常在第二种解决方案中我们可以接受db的开销时,将枚举值存储在db中的最佳方法是什么?是否有一般的确定设计模式规则?
谢谢。
解决方法
(我不知道)没有明确的设计规则,但是我更喜欢方法1。
是我更喜欢的方法。它很简单,枚举通常足够紧凑,以至于我开始记得数字的含义。
它更具可读性,但是在您需要时可能会妨碍重构或重命名枚举值。您将失去一些代码自由度。突然之间,您需要使DBA参与进来(取决于您在哪里/如何工作),只是为了更改枚举值或使它受苦。解析枚举对性能也有一定影响,因为像Locale这样的事情开始起作用,但可能可以忽略不计。
那解决什么问题呢?除非您希望增加连接的开销,否则表中的某个地方仍然有无法读取的数字。但是有时候,这也是正确的答案,具体取决于数据的使用方式。
编辑:
克里斯在评论中有一个很好的观点:如果您不赞成采用数字方法,则应明确分配值,以便也可以对它们重新排序。例如:
public enum Foo
{
Bar = 1,Baz = 2,Cat = 9,//Etc...
}
,我之前见过的一个想法是您的选择3或更少
数据库中的表(用于外键等)
客户端代码中匹配的Enum
启动检查(通过数据库调用)以确保它们匹配
数据库表表可以具有触发器或检查约束,以减少更改的风险。它不应该具有任何写权限,因为数据与客户端代码版本绑定在一起,但是它增加了安全因素,以防DBA崩溃
如果您有其他客户端正在读取代码(这是很常见的),则数据库具有完整的数据。