我需要以易于索引的方式存储实体的所有版本,并且想知道是否有人对要使用的系统有任何输入。
如果没有版本控制,系统只是一个关系数据库,每个人都有一行,例如人。如果此人的状态发生更改,则更改该行以反映此情况。通过版本控制,应该以这样的方式更新条目,以便我们可以始终返回到以前的版本。如果我可以使用时态数据库,这将是免费的,我可以问'昨天下午2点生活在都柏林和30岁'的所有人的状态。不幸的是,似乎没有任何成熟的开源项目能够做到时间。
执行此操作的一个非常讨厌的方法是每个状态更改插入一个新行。这导致重复,因为一个人可以有许多字段,但每次更新只有一个更改。在给定时间戳的情况下为每个人选择正确的版本也很慢。
理论上应该可以使用关系数据库和版本控制系统来模拟时态数据库,但这听起来非常可怕。
所以我想知道是否有人之前遇到类似的东西以及他们如何接近它?
更新 正如Aaron所建议的那样,我们目前使用的查询(在mysql中)。我们的桌子上的行数肯定很慢,行数> 200k。 (id =表键,person_id =每人ID,如果此人有很多修订,则重复)
从person p中选择名称,其中p.id =(从person_id = p.person_id和timestamp< =:timestamp)的人中选择max(id)
更新 看起来最好的方法是使用临时数据库,但鉴于没有任何开源数据库,下一个最好的方法是每次更新存储一个新行。唯一的问题是重复未更改的列和慢查询。
答案 0 :(得分:2)
有两种方法可以解决这个问题。两者都假设您始终插入新行。在每种情况下,您都必须插入一个时间戳(created
),告诉您何时“修改”了一行。
第一种方法使用数字来计算已有的实例数。主键是对象键加上版本号。这种方法的问题似乎是你需要select max(version)
进行修改。在实践中,这很少是一个问题,因为对于来自应用程序的所有更新,您必须首先加载该人员的当前版本,修改它(并增加版本),然后插入新行。所以真正的问题是这种设计使得很难在数据库中运行更新(例如,为许多用户分配属性)。
下一种方法使用数据库中的链接。您可以为每个对象分配一个新密钥而不是复合密钥,并且您有一个replacedBy
字段,其中包含下一个版本的密钥。这种方法可以很容易地找到当前版本(... where replacedBy is NULL
)。但是,更新是一个问题,因为您必须插入新行并更新现有行。
要解决此问题,您可以添加后退指针(previousVersion
)。这样,您可以插入新行,然后使用后退指针更新以前的版本。
答案 1 :(得分:0)
这是关于时态数据库的文献({3}}
的一个(有点过时)调查我建议花一些时间与这些参考文献和/或http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf坐下来试图找到适合您数据模型的一些好技术。祝你好运!