保持枚举和表格同步


11

我正在制作一个将数据发布到数据库的程序,并且遇到了我确定熟悉的模式:一个最有可能(很可能)固定值的简短表,它用作枚举。因此,假设下表名为Status

  状态
  编号说明
  --------------
   0未处理
   1个待处理
   2已处理
   3错误

在我的程序中,我需要确定另一个表的状态ID,或者可能用新的状态ID更新记录。

我可以在一个枚举中对状态ID进行硬编码,并希望没人能更改数据库。或者,我可以预取基于上述说明的值(从而硬编码代替)。

保持这两个枚举和表同步的正确方法是什么?


为什么要保持同步而不同步?同步(说出来)很奇怪!
MrFox 2012年

1
@suslik两者的发音相同。同步同步
MPelletier

1
具有枚举和数据库表是重复的。除非数据库表将被其他应用程序使用,否则我将放弃该表,而仅使用枚举。如果该表将在多个应用程序中使用,请改为在运行时从数据库中加载状态。
彼得·史密斯

这取决于上下文。在这种情况下,作为工作流或任务状态值,由于流程经常会发生变化,我倾向于使它们保持动态而不是静态。并倾向于在软件发布时间表之外进行更改。另一方面,如果它是一项稳定的服务,不太可能引入新状态或删除现有状态,那么我可能会更不得不对枚举进行硬编码/对其进行规范化(取决于以后使用记录的方式)。
JustinC

@PeterSmith如果仅在Java枚举中而不在表中,则数据库无法强制执行约束。您将要约束数据库中的值,不是吗?
戴维·康拉德

Answers:


5

我会在您的程序中对枚举进行硬编码,因为我怀疑这些不同的状态会影响您的程序逻辑。如果您具有新状态,那么您的程序应该如何应对这种新状态?

因为数据库是应用程序的一部分,所以我认为在不咨询其他方面的情况下影响一个数据库是没有意义的。


与新状态无关(它肯定会保证对数据库和程序进行修改),而不仅仅是ID值。
MPelletier

2
我不明白为什么您要更改ID值而不更改其含义。这些枚举不会自动增加,而实际上只是为了提高调试数据库人员的可读性,因为通常您的应用程序将进行查询,并且它已经知道ID的含义pending。当然,有一张Status表可以为您提供参照完整性,但这超出了我要提出的观点。
马修

是的,就是这个主意。但是,如果我将ID设置为一个到另一个的位置,那么我正在假设它们都是正确的。这是一个松散的链接,不是吗?
MPelletier

3
我们一直在进行这些假设,如果您想到了表定义,则我们的程序会在编写查询时假设定义是这样的。该Status表不应在应用程序运行时视为动态表,因此我不认为您应该这样阅读它。
马修

8

我通常会在应用程序启动时将此数据加载到静态缓存中(通常在HashMap或类似的东西中)。它避免了仅由于枚举已被某种方式修改而不得不重新编译的方法。


2

由于这些状态是它们,因此应将它们硬编码到应用程序中,以确保没有任何数据库更改都会破坏您的程序(至少不容易)。这很重要,因为必须首先对必须添加的每个状态进行编码,而不仅仅是将它们添加到数据库中。

例如,在您需要提取报告的情况下,您仍应将这些状态值及其正确的描述写入数据库。

通常,我有一个小的代码段,它将连接到数据库并验证特定表中列出的状态是否都具有与我在内存中硬编码的相同的id / name值。如果它们不匹配,我将中止软件的执行。

根据您的需求,您可能希望实现稍微不同的行为,但是总的来说,无论如何都要对这些状态进行硬编码是个好主意。


2

我们的项目中有类似的问题(旧版代码,万岁!),主要问题是“枚举表永远都不会改变”,直到它们改变并且代码中断为止。我有两种缓解策略,以缓解自己一直在朝着缓慢方向迁移的趋势。

首先也是最好的办法是,尽可能消除对这些值的直接引用。总是问:“为什么我需要直接使用枚举值?” 在许多情况下,这表明该代码具有太多硬编码的假设或正在尝试对数据进行过多的处理。看看您是否无法在数据库中建立更好的关系,或者无法获得更灵活的代码来处理所操纵的内容。

当那行不通时,我去计划B:代码生成。由于表很少更改,并且我们会定期发布新版本,因此代码生成器可以读取枚举表并编写枚举代码。然后在项目中使用此动态生成的库。如果数据库发生更改,下一个构建将无法编译,这比获取神秘的运行时错误要好得多。


您将如何消除对枚举的引用?例如,在这种情况下,您正在按状态排序或搜索。在数据库中拥有一些神奇的价值也不适合我。这就是查找表的用途。
nportelli 2013年

过去,我做相反的事情。每当枚举中的代码发生更改时,在应用程序启动时,它将这些值同步到数据库。这里的代码是真理的源头。数据库是它的表示。通常,我会忽略代码无法理解的数据库中的值,但是通过这种方式,我确实获得了一种在需要时自动清理数据库的机制。
Anshul
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.