(与版本化数据库模式无关)
与数据库接口的应用程序通常具有由来自许多表的数据组成的域对象.假设应用程序支持这些域对象的CVS意义上的版本控制.
对于某些仲裁域对象,您将如何设计数据库模式来处理此要求?有经验可以分享吗?
仔细考虑修订的要求.一旦您的代码库具有内置于操作系统中的普遍历史记录跟踪,它将变得非常复杂. 保险 承保 系统对此尤其不利,模式通常运行超过1000个表.查询也往往非常复杂,这可能会导致性能问题.
如果历史状态实际上仅用于报告,则考虑实施"当前状态"事务系统,其后面挂有数据仓库结构以跟踪历史记录. 慢慢改变维度是一种更简单的跟踪历史状态的结构,而不是试图将特殊历史跟踪机制直接嵌入到您的操作系统中.
此外,对于"当前状态"系统,更改数据捕获更简单,对记录进行了更改 - 记录的主键不会更改,因此您不必匹配包含同一实体的不同版本的记录一起.一个有效的CDC机制将使增量仓库加载过程相当轻量级并且可以非常频繁地运行.如果您不需要对历史状态进行最新的跟踪(几乎,但不完全和矛盾),这可以是一个有效的解决方案,其代码库比直接构建到应用程序中的完整历史记录跟踪机制简单得多.
我过去使用的一种技术是在数据库中使用"代"的概念,每次更改都会增加数据库的当前代数 - 如果使用subversion,请考虑修订.每条记录都有2个与之关联的代数(表中有2个额外的列) - 记录开始有效的代,以及它停止生成的代.如果数据当前有效,则第二个数字将为NULL或其他一些通用标记.
所以要插入数据库:
增加世代号
插入数据
使用有效的from标记该数据的生存期,并将有效值标记为NULL
如果您要更新一些数据:
将所有要修改的数据标记为当前世代号有效
增加世代号
使用当前世代号插入新数据
删除只是将数据标记为在当前一代终止.
要获取特定版本的数据,请查找您正在使用的生成并查找在这些生成版本之间有效的数据.
例:
创造一个人.
|Name|D.O.B |Telephone|From|To | |Fred|1 april|555-29384|1 |NULL|
更新电话号码
|Name|D.O.B |Telephone|From|To | |Fred|1 april|555-29384|1 |1 | |Fred|1 april|555-43534|2 |NULL|
删除fred:
|Name|D.O.B |Telephone|From|To | |Fred|1 april|555-29384|1 |1 | |Fred|1 april|555-43534|2 |2 |