2012-07-02 45 views
5

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

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

回答

2

我更喜欢为每个版本化表格增加历史表格。与主表time_fromtime_to附加字段相同的结构。 透明充满触发器。最近修订的time_to设置在遥远的未来。

指定时刻状态可以查询检索这样的:

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

至于我,主表中存储的历史是不是一般的好主意,因为它检索或加入现有数据时需要复杂的条件。

+0

所以主表具有最新的数据。那么“历史”表格有每个版本的副本?这是否打破标准化? – StackOverflowNewbie

+0

是的,非规范化发生,它是简单的价格(历史状态是从主表上简单的'INSERT','DELETE','UPDATE'自动生成的)和最新版本的性能(例如主表具有基于数据的索引历史有日期索引)。 如果最新修订版本不是主要修订版本,则此方法可能会因标准化失效而受损。 – vearutop

0

打开MySQL的binary logging并使用它。

+0

我认为这个问题是关于查询历史。 – MaxSem

0

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

  • 它们有_HISTORY后缀名;
  • 他们有2个额外的字段,start_dtend_dt,指示对象实例的生命周期;
  • start_dtNOT NULL,end_dt可以是NULL,它表示该实例是当前的并且不受其时间的限制;
  • ,可以插入未来变化日,说你想从1/Jan-2013激活一个新的公司名称,然后你需要设置当前实例的end_dt31/Dec-2012 23:59:59并插入的1/Jan-2013 00:00:00start_dt的新纪录;
  • 有时我也加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. 我可以很容易地计划和维护未来的变化。

希望这会对你有帮助。

0

最难的部分不是“基本”表的版本控制 - 您只需单独对它们进行版本化,就像单独使用一张表一样。

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

你打算怎么做取决于具体项目的要求。下面是sales orders could be "historized"的一个例子,但也有许多其他变体可能。

0

Datadiff。 API支持的DB版本跟踪。

披露:

我建Datadiff。我需要一个解决方案,提供MongoDB中数据模型的可视历史记录,以帮助支持SASS产品。它也将与SQL数据库一起工作。

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