如何为 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:无冗余数据。 缺点:很难查询过去特定时间点的状态。
问题
- 您对我如何设计此应用程序的数据模型有其他建议吗?
- 如果真的没有更好的办法解决这个问题:我应该走哪条路?或者它主要取决于给定的用例,就像上面描述的例子一样?
- 如果我选择第二种方法,查询过去特定时间点的状态会是什么样子?我能够在客户端解决这个问题,但我也想知道数据库方面的解决方案。 (PL/SQL也是可行的)
这个常用模型怎么样?
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
)
问题:
我在 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:无冗余数据。 缺点:很难查询过去特定时间点的状态。
问题
- 您对我如何设计此应用程序的数据模型有其他建议吗?
- 如果真的没有更好的办法解决这个问题:我应该走哪条路?或者它主要取决于给定的用例,就像上面描述的例子一样?
- 如果我选择第二种方法,查询过去特定时间点的状态会是什么样子?我能够在客户端解决这个问题,但我也想知道数据库方面的解决方案。 (PL/SQL也是可行的)
这个常用模型怎么样?
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
)