数据库设计:如何跟踪历史?

时间:2012-07-02 13:05:18

标签: mysql database database-design

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

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

5 个答案:

答案 0 :(得分:3)

我更喜欢为每个版本化表提供额外的历史表。与包含time_fromtime_to个附加字段的主表格相同的结构。 透明地填充触发器。最新修订版time_to设定为远期未来。

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

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

至于我,在主表中存储历史通常不是一个好主意,因为在检索或加入当前数据时需要复杂的条件。

答案 1 :(得分:1)

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

困难的部分是跟踪它们之间的连接

您打算如何做到这一点取决于特定项目的要求。以下是sales orders could be "historized"的示例,但还有许多其他变体。

答案 2 :(得分:0)

启用MySQL的binary logging并使用它。

答案 3 :(得分:0)

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

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

为了通过这样的设计获得适当的RI约束,我总是有2个用于版本化obejcts的表。说,对于Customer obejct,我有以下一组表:

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. 我可以轻松地计划和维护未来的变更。
  5. 希望这会对你有所帮助。

答案 4 :(得分:0)

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

完全披露:

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

您可以使用key:val表示法进行基本查询。即id:123