4

我的整个数据库偶尔会有错误的条目,但我不想直接更改数据,而是希望能够保持对更改的修订。

这些变化很少发生。

理想情况下是这样的: -

 (original table fields) | revision_version | origin | user | timestamp

假设我有一个名为posts的表,其架构如下:-

title | description | timestamp | author

因此将创建一个名为posts_revisions的附加表:-

title | description | timestamp | author | revision_version | origin | user | timestamp
  • origin是变化的来源,无论是机器人、用户生成的还是您拥有的。

正如您可以想象的那样,这是对现有数据库的一个相当大的更改,我目前关心的是检查每个查询的 _revisions 表的性能损失。这是这类事情的最佳实践吗?

4

2 回答 2

2

对于这类问题,我保留了一个当前表和一个历史表。

历史记录表具有以下附加列:

  • 历史ID
  • 生效日期
  • 结束日期
  • 版本号
  • 由...制作
  • 创建时间

生效日期和结束日期是值有效的时间跨度。每次记录发生更改时,版本都会增加。id、CreatedAt 和 CreatedBy 是我放入数据库中几乎每个表的列。

通常,我使用夜间作业保持历史记录表是最新的,这些作业比较表,然后使用 MERGE 合并数据。另一种方法是将所有更改包装在存储过程中,并在那里更新两个表。另一种选择是使用触发器,它检测何时发生更改。但是,我回避触发器,更喜欢前两种选择。

我必须承认,磁盘空间对于这些表来说并不是一个重要的考虑因素。因此,将数据存储两次是没有问题的,一次在结果中,一次在历史中。只在历史表中存储历史,而当前记录在“当前”表中,这只是一个小调整。

这种方法的一个缺点是改变了基表的结构。如果要添加列,则需要将其添加到历史表和基表中。

于 2012-08-02T13:52:28.943 回答
1

如果这些表用于汇总目的(尤其是业务用户,如果他们有一些 SQL 访问权限),我认为最好删除数据并将其放入另一个表中。虽然标志和修订有时很好,但当你必须按照那样做一些事情时,select sum(select someVar where revision_version=max(revision_version and someID=ID))它真的变得非常简单。

如果您有一个用于快速和讨厌的数据收集的表,请替换数据,如果需要,将旧数据放入修订表中。如果只有某些应用程序可以访问它并且它不是性能问题,那么请将其保留在主表中。

于 2012-08-02T12:57:46.443 回答