2

我需要以易于索引的方式存储实体的所有版本,并且想知道是否有人输入了要使用的系统。

如果没有版本控制,系统只是一个关系数据库,每个人都有一行。如果此人的状态发生变化,则该行将更改以反映这一点。使用版本控制,条目应该以这样的方式更新,以便我们总是可以回到以前的版本。如果我可以使用时态数据库,这将是免费的,我将能够询问“截至昨天下午 2 点住在都柏林且 30 岁的所有人的状态如何”。不幸的是,似乎没有任何成熟的开源项目可以做临时性的。

一个非常讨厌的方法是在每次状态更改时插入一个新行。这会导致重复,因为一个人可以有许多字段,但每次更新只能更改一个。然后为给定时间戳的每个人选择正确的版本也很慢。

理论上应该可以使用关系数据库和版本控制系统来模拟时间数据库,但这听起来很可怕。

所以我想知道是否有人以前遇到过类似的事情以及他们是如何解决的?

更新 正如 Aaron 所建议的,这是我们目前使用的查询(在 mysql 中)。超过 200k 行的表在我们的表上肯定很慢。(id = 表键,person_id = 每个人的 id,如果这个人有很多修订,则重复)

从人员 p 中选择姓名,其中 p.id =(从人员中选择 max(id),其中人员 ID = p.person_id 和时间戳 <= :timestamp)

更新 看起来最好的方法是使用临时数据库,但鉴于没有任何开源数据库,下一个最佳方法是每次更新存储一个新行。唯一的问题是重复未更改的列和缓慢的查询。

4

2 回答 2

3

有两种方法可以解决这个问题。两者都假设您总是插入新行。在每种情况下,您都必须插入一个时间戳 ( created),它会告诉您行何时“修改”。

第一种方法使用一个数字来计算您已经拥有多少个实例。主键是对象键加上版本号。这种方法的问题似乎是您需要select max(version)进行修改。实际上,这很少成为问题,因为对于应用程序的所有更新,您必须首先加载人员的当前版本,修改它(并增加版本),然后插入新行。所以真正的问题是这种设计使得在数据库中运行更新变得很困难(例如,将一个属性分配给许多用户)。

下一种方法使用数据库中的链接。你给每个对象一个新的键,而不是一个复合键,你有一个replacedBy包含下一个版本的键的字段。这种方法可以很容易地找到当前版本 ( ... where replacedBy is NULL)。但是,更新是一个问题,因为您必须插入新行并更新现有行。

为了解决这个问题,您可以添加一个反向指针 ( previousVersion)。这样,您可以插入新行,然后使用反向指针更新以前的版本。

于 2009-11-10T17:36:49.043 回答
0

这是对时间数据库文献的(有些过时的)调查:http ://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.91.6988&rep=rep1&type=pdf

我建议您花点时间与这些参考资料和/或Google Scholar坐下来尝试找到一些适合您的数据模型的好技术。祝你好运!

于 2009-11-10T21:37:33.670 回答