一组数据结构的变化类似于SVN?
Data structure for a set of changes similar to SVN?
到目前为止,我们一直在存储更改信息,如下所示。
想象一下,有一个变更集 table 结构,其中包含被称为对象的被更改的东西。该对象通过外键连接到外来元素。对象是这样创建的
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
现在我们改名,table改名后的样子
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
2015-04-29 23:30:01 | 2 | null | foo | null
这个结构正好是最小的。它完全包含我们所做的更改。但是要创建对象的当前版本,我们必须将更改加起来才能真正获得最终版本。例如
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
2015-04-29 23:30:01 | 2 | null | foo | null
*2015-04-29 23:30:01 | 2 | 123 | foo | none
* 标记最终版本,数据库中不存在。
因此,如果我们只准确地存储更改,我们还有更多工作要做。特别是当来自异物时 f
。如果我有多个对象 f
并且我想从我们的 table 获取对对象的所有更改,我必须创建一个有点丑陋的 SQL。这显然会变得更糟,你的异物越多。
基本上我要做的:
Select all F that I want and
Select all objects WHERE foreignKey = foreignId
OR Select all objects that have objectId in (Select all objects that have foreignKey = foreignId)
例如我必须 select 具有 foreignKey 123 的对象或具有 foreignKey 为 null 的元素,但存在一个具有相同 objectId 和 foreignKey 123 的条目。
依赖越多,这个SQL越丑。
我说清楚了吗?
在所有版本中始终保留所有字段会不会更容易
例如一个简单的名称更改得到:
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
2015-04-29 23:30:01 | 2 | 123 | foo | none
现在要创建差异,我必须比较两个版本,但我不必为 selecting 正确的元素或计算所述时间戳的最终版本做额外的工作。
您认为经过验证的最佳解决方案是什么?
svn 是怎么做到的?
对于您的用例,您建议的方法似乎更好。 LSM 树等键值存储的作用完全相同。他们只是编写对象的更新版本而不删除旧版本。如果在任何时候您需要所做的更改,我想您可以只比较两个相邻的版本。
如果您有很多可变长度的文本字段,第二种方法可能会使用更多 space,但这是速度和可维护性之间的权衡。
到目前为止,我们一直在存储更改信息,如下所示。 想象一下,有一个变更集 table 结构,其中包含被称为对象的被更改的东西。该对象通过外键连接到外来元素。对象是这样创建的
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
现在我们改名,table改名后的样子
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
2015-04-29 23:30:01 | 2 | null | foo | null
这个结构正好是最小的。它完全包含我们所做的更改。但是要创建对象的当前版本,我们必须将更改加起来才能真正获得最终版本。例如
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
2015-04-29 23:30:01 | 2 | null | foo | null
*2015-04-29 23:30:01 | 2 | 123 | foo | none
* 标记最终版本,数据库中不存在。
因此,如果我们只准确地存储更改,我们还有更多工作要做。特别是当来自异物时 f
。如果我有多个对象 f
并且我想从我们的 table 获取对对象的所有更改,我必须创建一个有点丑陋的 SQL。这显然会变得更糟,你的异物越多。
基本上我要做的:
Select all F that I want and
Select all objects WHERE foreignKey = foreignId
OR Select all objects that have objectId in (Select all objects that have foreignKey = foreignId)
例如我必须 select 具有 foreignKey 123 的对象或具有 foreignKey 为 null 的元素,但存在一个具有相同 objectId 和 foreignKey 123 的条目。
依赖越多,这个SQL越丑。
我说清楚了吗?
在所有版本中始终保留所有字段会不会更容易
例如一个简单的名称更改得到:
changesetId (Timestamp) | objectId | foreignKey | name (String) | description (String)
2015-04-29 23:28:52 | 2 | 123 | none | none
2015-04-29 23:30:01 | 2 | 123 | foo | none
现在要创建差异,我必须比较两个版本,但我不必为 selecting 正确的元素或计算所述时间戳的最终版本做额外的工作。
您认为经过验证的最佳解决方案是什么? svn 是怎么做到的?
对于您的用例,您建议的方法似乎更好。 LSM 树等键值存储的作用完全相同。他们只是编写对象的更新版本而不删除旧版本。如果在任何时候您需要所做的更改,我想您可以只比较两个相邻的版本。
如果您有很多可变长度的文本字段,第二种方法可能会使用更多 space,但这是速度和可维护性之间的权衡。