首先,您需要向表中添加一组属性:
- 版本 - 最后修改的时间(也可以是自动递增计数器而不是时间)。
- LastModifiedBy - 对进行最后修改的用户的引用(如果您存储了该修改)。
然后,您有几个关于如何存储版本历史记录的选项。你可以
为要存储历史记录的每个主表创建一个新表。该历史表将具有与主表相同的字段,但不会强制执行主键和外键。对于每个外键,还存储创建版本时引用条目的版本。
或者,您可以序列化有关您的实体的所有有趣的内容,并将您想要版本化的所有实体的所有序列化 blob 存储在一个全局历史表中(我个人更喜欢第一种方法)。
你如何填写你的历史表?通过更新和删除触发器。
- 在您的实体的更新触发器中 - 将所有以前的值复制到历史记录表。对于每个外键 - 还复制引用实体的当前版本。
- 在删除触发器中 - 基本上做同样的事情。
请注意,越来越多的现代系统并没有真正删除任何内容。他们只是将内容标记为已删除。如果您想遵循这种模式(它有几个好处) - 而不是删除添加 IsDeleted 标志到您的实体(当然,您必须在任何地方过滤已删除的实体)。
你如何看待你的历史?只需使用历史表,因为它具有与主表相同的所有属性 - 应该不是问题。但是 - 扩展外键时 - 确保引用的实体版本与您在历史记录表中存储的相同。如果不是 - 您需要转到该引用实体的历史记录表并在那里获取值。这样,您将始终对实体在那个时刻的样子有一个快照,包括所有引用。
除了以上所有 - 您还可以将实体的状态恢复到任何以前的版本。
请注意,此实现虽然简单,但可能会占用一些空间,因为它存储快照,而不仅仅是正在进行的更改。如果您只想存储更改 - 在更新触发器中,您可以检测哪些字段已更改,将它们序列化并存储在全局历史表中。这样,您至少可以在用户界面中显示已更改的内容以及由谁更改(尽管您可能无法恢复到以前的版本)。