Postgresql 数据库中的版本控制
我想在每次对金额敏感表进行更新时存储行的完整版本控制 到目前为止,我决定使用以下方法Postgresql 数据库中的版本控制,postgresql,database-design,Postgresql,Database Design,我想在每次对金额敏感表进行更新时存储行的完整版本控制 到目前为止,我决定使用以下方法 不允许更新 每次更新时,创建一个新的 表中的条目 然而,对于这种变化,我还没有决定什么是最好的数据库结构设计 当前结构 主键:id id(int) | amount(decimal) | other_columns 第一种方法 复合主键:id,版本 id(int) | version(int) | amount(decimal) | change_reason 1 | 1
id(int) | amount(decimal) | other_columns
第一种方法
复合主键:id,版本
id(int) | version(int) | amount(decimal) | change_reason
1 | 1 | 100 |
1 | 2 | 20 | correction
第二种方法
主键:id
id(int) | amount(decimal) | other_columns
[origin_id,version]上的唯一性索引
id(int) | origin_id(int) | version(int) | amount(decimal) | change_reason
1 | NULL | 1 | 100 | NULL
2 | 1 | 2 | 20 | correction
我建议使用一个新表来存储项的
唯一id
。这用作所有可用项的查找表
项目表格:
id(int)
1000
id(int) | item_id(int) | version(int) | amount(decimal) | change_reason
1 | 1000 | 1 | 100 | NULL
2 | 1000 | 2 | 20 | correction
对于存储item
所有更改的表,我们将其称为item\u changes
表item_id
是item
表的id
的外键。项目
表与项目_变化
表之间的关系为一对多
关系
项目变更表格:
id(int)
1000
id(int) | item_id(int) | version(int) | amount(decimal) | change_reason
1 | 1000 | 1 | 100 | NULL
2 | 1000 | 2 | 20 | correction
这样,item\u id
将永远不会为NULL
,因为它是item
表的有效外键。我建议为item创建一个新表,该表存储唯一id
。这用作所有可用项的查找表
项目表格:
id(int)
1000
id(int) | item_id(int) | version(int) | amount(decimal) | change_reason
1 | 1000 | 1 | 100 | NULL
2 | 1000 | 2 | 20 | correction
对于存储item
所有更改的表,我们将其称为item\u changes
表item_id
是item
表的id
的外键。项目
表与项目_变化
表之间的关系为一对多
关系
项目变更表格:
id(int)
1000
id(int) | item_id(int) | version(int) | amount(decimal) | change_reason
1 | 1000 | 1 | 100 | NULL
2 | 1000 | 2 | 20 | correction
这样,item\u id
将永远不会为NULL
,因为它是item
表的有效外键。最好的方法是使用版本标准格式(vnf)。这是我给出的一种简洁的方法,可以跟踪特定表的特定字段的所有更改
静态表包含静态数据,例如PK和其他属性,这些数据在实体的生命周期内不会更改,或者不需要跟踪这些更改
版本表包含需要跟踪的所有动态属性。最好的设计使用一个视图,将静态表与版本表中的当前版本连接起来,因为当前版本可能是应用程序最需要的。视图上的触发器维护静态/版本化设计,而应用程序不需要知道任何有关它的信息
上面的链接还包含一个指向文档的链接,该文档提供了更多详细信息,包括获取当前版本或“回顾”所需任何版本的查询。最好的方法是使用版本标准格式(vnf)。这是我给出的一种简洁的方法,可以跟踪特定表的特定字段的所有更改
静态表包含静态数据,例如PK和其他属性,这些数据在实体的生命周期内不会更改,或者不需要跟踪这些更改
版本表包含需要跟踪的所有动态属性。最好的设计使用一个视图,将静态表与版本表中的当前版本连接起来,因为当前版本可能是应用程序最需要的。视图上的触发器维护静态/版本化设计,而应用程序不需要知道任何有关它的信息
上面的链接还包含一个指向文档的链接,该文档提供了更详细的信息,包括获取当前版本或“回顾”所需的任何版本的查询。为什么不选择SCD-2(缓慢变化的维度),这是描述问题最佳解决方案的规则/方法。下面是SCD-2的优点和使用示例,它为数据库创建了标准设计模式
类型2-创建新的附加记录。在这种方法中,维度更改的所有历史记录都保存在数据库中。通过向维度表添加具有新代理键的新行,可以捕获属性更改。前一行和新行都包含自然键(或其他持久标识符)作为属性。此方法中还使用了“生效日期”和“当前指标”列。当前指示器设置为“Y”的记录只能有一条。对于“生效日期”列,即开始日期和结束日期,当前记录的结束日期通常设置为值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个额外的列,开始日期、结束日期、当前标志,即可正确跟踪记录。当第一次插入@source记录时,此表将存储值为:
id | amount | start_date |end_date |current_flag
1 100 01-Apr-2018 NULL Y
并且,当更新同一条记录时,您必须将前一条记录的“结束日期”更新为当前系统日期,“当前标志”更新为“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
为什么您不选择SCD-2(缓慢变化的维度),这是描述问题最佳解决方案的规则/方法。下面是SCD-2的优点和使用示例,它为数据库创建了标准设计模式
类型2-创建新的附加记录。在这种方法中,维度更改的所有历史记录都保存在数据库中。通过向维度表添加具有新代理键的新行,可以捕获属性更改。前一行和新行都包含自然键(或其他持久标识符)作为属性。此外,“生效日期”和“当前指标”列也用于此字段