版本控制数据库持久对象,你会怎样?
(与版本控制数据库模式无关)
与数据库交互的应用程序通常具有由多个表中的数据组成的域对象。 假设应用程序支持这些域对象的版本控制,就CVS而言。
对于一些仲裁域对象,你将如何devise一个数据库模式来处理这个需求? 任何经验分享?
仔细考虑修改的要求。 一旦你的代码库已经在操作系统中build立了普遍的历史跟踪,它将变得非常复杂。 保险 承保 体系对此尤其不利,模式通常超过1000张桌子。 查询也往往是相当复杂的,这可能会导致性能问题。
如果历史状态只是报告的必要条件,那么可以考虑实施一个“现状”的交易系统,用一个数据仓库结构来跟踪历史。 缓慢变化的维度跟追溯历史状态相比,试图将一个专门的历史追踪机制直接embedded到你的操作系统中是一个简单得多的结构。
此外,对于“当前状态”系统, 更改数据捕获更简单,对logging进行了更改 – logging的主键不会更改,因此您不必匹配包含同一实体的不同版本的logging一起。 一个有效的CDC机制将使增量仓库加载过程相当轻量级,并可能频繁运行。 如果你不需要对历史状态进行最新的跟踪(几乎,但不完全是矛盾的),与直接构build到应用程序中的完整的历史跟踪机制相比,这可以是一个更简单的代码库的有效解决scheme。
过去我使用过的一种技术是在数据库中有一个“世代”的概念,每一个变化都会增加数据库的当前代数 – 如果你使用颠覆的话,考虑修订。 每个logging有2个与之关联的世代(表格上有2个额外的列) – logging开始生效的时间,以及停止生成的时间。 如果数据当前有效,则第二个数字将是NULL或其他通用标记。
所以要插入到数据库中:
- 增加世代号码
- 插入数据
- 使用有效来标记该数据的生命周期,以及有效的NULL
如果你正在更新一些数据:
- 将所有即将被修改的数据标记为对当前世代号有效
- 增加世代号码
- 插入新的数据与当前世代号码
删除只是将数据标记为终止在当前的一代。
要获取特定版本的数据,请查找您要使用的版本,并在这些版本之间查找有效的数据。
例:
创build一个人。
|Name|DOB |Telephone|From|To | |Fred|1 april|555-29384|1 |NULL|
更新电话号码
|Name|DOB |Telephone|From|To | |Fred|1 april|555-29384|1 |1 | |Fred|1 april|555-43534|2 |NULL|
删除fred:
|Name|DOB |Telephone|From|To | |Fred|1 april|555-29384|1 |1 | |Fred|1 april|555-43534|2 |2 |
严格版本的替代方法是将数据分成两个表格:当前和历史。
当前表格包含所有实时数据,并具有您构build的所有性能的好处。任何更改都会先将当前数据写入关联的“历史logging”表格以及date标记,该标记说明何时更改。
如果你使用Hibernate, JBoss Envers可能是一个选项。 你只需要使用@Audited
来注解类来保存他们的历史。
您需要在主表中包含所有版本之间通用信息的主logging。
然后,每个子表使用主loggingID +版本号作为主键的一部分。
这可以在没有主表的情况下完成,但根据我的经验,这往往会使SQL语句变得更加混乱。
一个简单的傻瓜式的方法是向表中添加一个版本列并存储对象的版本,并根据该版本号select合适的应用程序逻辑。 这样你也可以获得向后兼容性,成本很低。 这总是很好
ZoDB + ZEO实现了基于版本的数据库,并完全回滚到任何时间点的支持。 去检查一下。
不好的部分:这是Zope绑定。
一旦一个对象被保存在一个数据库中,我们可以正确地修改这个对象任意多次。如果我们想知道一个对象被修改了多less次,那么我们需要应用这个版本化的概念。
当我们使用版本控制时,当数据库中的对象首次被保存时,hibernate会将版本号作为零插入。 后来,当对特定对象进行修改时,hibernate会自动增加版本号。 为了使用这个版本概念,我们需要在我们的应用程序中进行以下两个更改
Add one property of type int in our pojo class. In hibernate mapping file, add an element called version soon after id element