在数据库中进行版本控制

时间:2018-05-01 14:32:40

标签: postgresql database-design

我想在每次更新数量敏感表时存储行的完整版本。

到目前为止,我已决定使用以下方法。

  1. 不允许更新。
  2. 每次更新时都会创建一个新的 进入表格。
  3. 但是,我还未决定这次变更的最佳数据库结构设计是什么。

    当前结构

    主键:id

    id(int) | amount(decimal) | other_columns 
    

    第一种方法

    复合主键:id,版本

    id(int) | version(int) | amount(decimal) | change_reason 
     1      | 1            | 100             | 
     1      | 2            | 20              | correction
    

    第二种方法

    主键:id

    [origin_id,version]

    的唯一性索引
    id(int) | origin_id(int) | version(int) | amount(decimal) | change_reason 
     1      | NULL           |  1           | 100             | NULL
     2      | 1              |  2           | 20              | correction
    

3 个答案:

答案 0 :(得分:2)

最好的方法是使用Version Normal Form(vnf)。 Here是我给出的一个简单方法,可以跟踪特定表格特定字段的所有更改。

静态表包含静态数据,例如PK和其他在实体生命周期内不会更改的属性,或者无需跟踪此类更改。

版本表包含需要跟踪的所有动态属性。最好的设计使用一个视图,它将静态表与版本表中的当前版本连接起来,因为当前版本可能是您的应用程序最常需要的版本。视图上的触发器保持静态/版本化设计,而应用程序不需要知道任何有关它的信息。

上面的链接还包含一个文档的链接,该文档更详细,包括查询以获取当前版本或“回顾”您需要的任何版本。

答案 1 :(得分:1)

我建议使用一个新表来存储unique id项。这用作所有可用项目的查找表。

表:

id(int)
1000

对于存储item所有更改的表格,我们将其称为item_changes表格。 item_idFOREIGN KEYitemiditem表与item_changes表之间的关系为one-to-many关系。

item_changes 表:

id(int) | item_id(int)   | version(int) | amount(decimal) | change_reason 
 1      | 1000           |  1           | 100             | NULL
 2      | 1000           |  2           | 20              | correction

有了这个,item_id永远不会是NULL,因为它是有效的FOREIGN KEYitem表。

答案 2 :(得分:1)

为什么你不选择 SCD-2 (慢慢改变维度),这是描述问题最佳解决方案的规则/方法。以下是SCD-2的优势和使用示例,它为数据库制定了标准设计模式。

类型2 - 创建新的附加记录。在此方法中,维度更改的所有历史记录都保存在数据库中。通过向维度表添加具有新代理键的新行来捕获属性更改。先行和新行都包含自然键(或其他持久标识符)作为属性。此方法中还使用了“生效日期”和“当前指标”列。当前指标设置为“Y”时,只能有一条记录。对于“生效日期”列,即start_date和end_date,当前记录的end_date通常设置为值9999-12-31。在类型2中引入对维度模型的更改可能是非常昂贵的数据库操作,因此不建议在将来可以添加新属性的维度中使用它。

id | amount | start_date    |end_date       |current_flag
1    100      01-Apr-2018    02-Apr-2018     N
2    80       04-Apr-2018    NULL            Y

详细说明::::

在此,您需要添加3个额外的列 START_DATE,END_DATE,CURRENT_FLAG 以正确跟踪您的记录。当第一次记录插入@ource时,该表将值存储为:

id | amount | start_date    |end_date       |current_flag
1    100      01-Apr-2018    NULL            Y

并且,当更新相同的记录时,您必须将前一记录的“END_DATE”更新为current_system_date,将“CURRENT_FLAG”更新为“N”,并插入第二条记录,如下所示。因此,您可以跟踪记录的所有内容。如下......

id | amount | start_date    |end_date       |current_flag
1    100      01-Apr-2018    02-Apr-2018     N
2    80       04-Apr-2018    NULL            Y