6

数据库设计中维护修订历史的一般策略是什么?如果只是我要处理的一张桌子,我认为这不会那么难。只需将每个更新保存为表中的新记录。最后一条记录将始终是最新版本。

但是当数据存储在多个表中时,有什么好的设计方法可以跟踪修订?

4

5 回答 5

3

我更喜欢为每个版本化表添加额外的历史表。time_from与带有time_to附加字段的主表结构相同。透明地充满了触发器。time_to最新版本设置为遥远的未来。

可以使用如下查询检索指定时刻的状态:

SELECT * FROM user_history 
WHERE time_from >= '2012-02-01' AND time_to <= '2012-02-01' 

对我来说,在主表中存储历史通常不是一个好主意,因为它在检索或连接当前数据时需要复杂的条件。

于 2012-07-02T13:09:45.320 回答
2

困难的部分不是“基本”表的版本控制——您只需单独对它们进行版本控制,就像您对单独的单个表进行版本控制一样。

困难的部分是跟踪它们之间的联系

您将如何做到这一点取决于特定项目的要求。这是一个销售订单如何被“历史化”的例子,但也有许多其他的变化。

于 2012-07-02T17:52:24.593 回答
0

打开 MySQL 的二进制日志并使用它。

于 2012-07-02T13:15:59.807 回答
0

我正在使用方法,其中我正在处理的每个对象至少有 1 个所谓的实例表,我在其中保存倾向于随时间变化的数据。通常,此类表遵循以下概念:

  • 他们_HISTORY的名字有后缀;
  • 它们有 2 个额外的字段start_dtend_dt,表示对象实例的生命周期;
  • start_dtis NOT NULL, end_dtcan be NULL, 表示该实例是当前的且不受时间限制;
  • 可以插入未来日期的更改,假设您希望从 激活新的公司名称,1/Jan-2013那么您需要将end_dt当前实例设置为31/Dec-2012 23:59:59并插入一条新start_dt记录1/Jan-2013 00:00:00
  • 有时我也会添加revision字段,如果有必要跟踪修订。

为了在这种设计中获得适当的 RI 约束,我总是有 2 个用于版本化对象的表。说,对于Customer对象,我有以下一组表:

customer (customer_id INTEGER, PRIMARY KEY (customer_id));
customer_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP,
                  name VARCHAR(50), sex CHAR(1), ...,
                  PRIMARY KEY (customer_id, start_dt));
customer_bank_history (customer_id INTEGER, start_dt TIMESTAMP, end_dt TIMESTAMP,
                       bank_id INTEGER, iban VARCHAR(34));

customer(customer_id)在我用来构建外键的所有其他地方。查询实际客户详细信息很简单:

SELECT c.customer_id, ch.name, ch.sex
  FROM customer c
  JOIN customer_history ch ON c.customer_id = ch.customer_id
       AND now() BETWEEN ch.start_dt AND coalesce(end_dt, now());

为什么我更喜欢这样的设计:

  1. 我通过设计在数据库级别对对象实例进行了版本控制;
  2. 我必须维护更少的表格;
  3. 如果有人丢弃/禁用任何触发器,则不可能丢失历史记录;
  4. 我可以轻松地计划和维护未来的变更。

希望这会帮助你。

于 2012-07-02T14:46:37.950 回答
0

数据差异。API 驱动的数据库修订跟踪。

全面披露:

我建立了 Datadiff。我需要一个提供 MongoDB 中数据模型的可视化历史的解决方案,以帮助支持 SASS 产品。它也适用于 SQL 数据库。

您可以使用key:val符号进行基本查询。IEid:123

于 2015-06-29T18:09:23.003 回答