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

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

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

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

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

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

select name from person p where p.id = (select max(id) from person where person_id = p.person_id and timestamp <= :timestamp)

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

有帮助吗?

解决方案

有解决这个方法有两种。这两个假定你总是插入新行。在任何情况下,必须插入一个时间标记(created),其告诉你什么时候连续被“修饰的”。

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

在接下来的方法使用在数据库中的链接。取而代之的是组合键,你给每个对象一个新的密钥,你必须包含的下一个版本的密钥replacedBy场。这种方法可以很方便地找到最新的版本(... where replacedBy is NULL)。更新是一个问题,不过,因为你必须插入新行和更新现有的一个。

要解决这个问题,可以添加一个返回指针(previousVersion)。通过这种方式,你可以插入新行,然后使用背面的指针更新之前的版本。

其他提示

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

我建议花很多时间坐下来阅读这些参考资料和/或 谷歌学术 尝试找到一些适合您的数据模型的好技术。祝你好运!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top