我想在每次更新数量敏感表时存储行的完整版本。
到目前为止,我已决定使用以下方法。
但是,我还未决定这次变更的最佳数据库结构设计是什么。
当前结构
主键: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
答案 0 :(得分:2)
最好的方法是使用Version Normal Form(vnf)。 Here是我给出的一个简单方法,可以跟踪特定表格特定字段的所有更改。
静态表包含静态数据,例如PK和其他在实体生命周期内不会更改的属性,或者无需跟踪此类更改。
版本表包含需要跟踪的所有动态属性。最好的设计使用一个视图,它将静态表与版本表中的当前版本连接起来,因为当前版本可能是您的应用程序最常需要的版本。视图上的触发器保持静态/版本化设计,而应用程序不需要知道任何有关它的信息。
上面的链接还包含一个文档的链接,该文档更详细,包括查询以获取当前版本或“回顾”您需要的任何版本。
答案 1 :(得分:1)
我建议使用一个新表来存储unique id
项。这用作所有可用项目的查找表。
项表:
id(int)
1000
对于存储item
所有更改的表格,我们将其称为item_changes
表格。 item_id
是FOREIGN KEY
到item
表id
。 item
表与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 KEY
到item
表。
答案 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