对于长篇大论的标题感到抱歉,但要求/问题是相当具体的.
参考下面的示例(但非常简化)结构(在伪造的SQL中),我希望能够更好地解释它.
TABLE StructureName { Id GUID PK, Name varchar(50) NOT NULL } TABLE Structure { Id GUID PK, ParentId GUID, -- FK to Structure NameId GUID NOT NULL -- FK to StructureName } TABLE Something { Id GUID PK, RootStructureId GUID NOT NULL -- FK to Structure }
可以看出,Structure是一个简单的树结构(不担心为这个问题排序孩子).StructureName是翻译系统的简化.最后,"Something"只是引用树根结构的东西.
这只是需要进行版本化的许多表中的一个,但是这个表在大多数情况下都是一个很好的例子.
需要对Structure表的名称和/或树"布局"的任何更改进行版本化.以前的版本应始终可用.
似乎有一些可能性来解决这个问题,比如复制整个结构,但大多数方法都会导致一个"松散"的参照完整性.例如,如果遵循这种方法,则必须复制"Something"记录,假定根结构将是新记录,并且具有新ID.
其他可能解决方案的途径是研究Wiki如何处理这个问题或进一步研究如何正确处理版本控制系统的工作方式.
目前,我觉得如何以通用方式继续这一点感到有点无能为力.
任何想法将不胜感激.
谢谢
leppie
一些快速的想法:
完整副本:创建结构的副本,但是对于每个表version_id
,向PK和所有FK 添加一列; 因此,您可以使用完整的参照完整性创建生命数据的副本.
亲:轻松查询历史记录
con:大量(复制的冗余数据)
更改副本:仅复制实际更改的内容以及valid_from
/ valid_to
data.
亲:复制的数据量很小
con:难以查询,因为必须间隔加入
变化:这适用于两种方案.您可以将当前记录保存在与旧版本相同的表中,而不是创建结构的副本,而是将其标记为当前记录.
pro:数量较少的表格,更容易混合历史和当前信息
con:正常操作在更大的表上运行,这将导致性能影响
审计日志:根据您的实际要求,只需创建如下审计跟踪就足够了:
id, timestamp, changed_table, changed_column, old_value, new_value, changed_by
您可以将其扩展为完整的表结构:
transaction, table_change, changed_column
pro:泛型,因此很容易为大量表实现
con:如果你需要在给定时间重建一组记录的状态,查询将成为一场噩梦
我写了一篇关于版本化的各种方法的博客,但要注意:它是用德语写的.
数据仓库人员有几种"缓慢变化的维度"的算法.
更复杂的算法提供围绕维度值的数据范围,以指示何时有效.
根据您的版本控制要求,您可以从Kimball的数据仓库工具包中完成其中一项工作.
将版本号分配给结构表的行.这意味着你必须做一些推理来收集一个完整的结构.它包括与早期版本中未更改的行联合的选定版本号.
为结构表的行分配日期范围或版本范围.这意味着某些行具有开始日期和结束日期; 在不可能的未来,某些行将在某个时代有结束日期.或者,如果您使用版本号,您将拥有一个起始端对或一个起始无穷大对,表明该行仍然是当前的.然后,您可以轻松查询"今天"有效的行或应用于请求的版本.
克隆每个版本的结构.这令人不愉快,因为克隆操作很昂贵.但是,查询很简单,因为整个结构可以使用单个一致的版本号.