如何为 n:m 关系设计历史记录

How to design a history for n:m relations

问题:

我在 table A 和另一个 table B 之间有一个 n:m 关系,并且需要有这个关系的完整历史记录,换句话说,我必须能够重现过去任何一点的状态。

想法:

我的第一个尝试是通过插入一个虚拟 table 来将关系分解为 1:m 和 m:n 关系,以便在任何给定时间保存关系的状态变化发生。像这样:

TABLE A         TABLE B
--------        ---------
ID   INT        ID    INT                   

TABLE HIST             TABLE CROSS_REF
----------             -----------------
ID        INT          REF_B_ID      INT
REF_A_ID  INT          REF_HIST_ID   INT
VERSION   TIMESTAMP

亲:查询所需资料方便。 缺点: 这种尝试会产生大量冗余数据,尤其是当 "B"-Side 很大并且只有很小的变化时。 (例如在用例 "Company -- Employee" 中)

第二种方法是维护两个 n:m 关系,一个用于当前状态,一个用于发生的更改。

TABLE A         TABLE B
--------        ---------
ID   INT        ID    INT                   

TABLE CHANGES          TABLE CROSS_REF
----------             -----------------
REF_A_ID     INT          REF_A_ID      INT
REF_B_ID     INT          REF_B_ID   INT
ACTION_TIME  TIMESTAMP
ACTION_TYPE  VARCHAR

Pro:无冗余数据。 缺点:很难查询过去特定时间点的状态。

问题

这个常用模型怎么样?

create table cross_ref
  ( a_id    references a
  , b_id    references b
  , from_ts timestamp
  , to_ts   timestamp
  , primary key (a_id, b_id, from_ts)
  );

(注意我像你一样使用timestamp;通常我会使用date)