多对多修订的数据库设计?

时间:2011-08-22 15:48:30

标签: sql many-to-many revision

我的问题与Database Design for Revisions?有关,但更复杂。

我有两张表,它们之间有多对多的关系。我们称他们为A和B.

A: A.id, A.data, A.last_change_time
B: B.id, B.data
A_B: A_B.A_id, A_B.B_id, A_B.connected_since_time, A_B.some_status_enum

A_B连接器表必须支持修订。如果A中的元素与B中的元素之间的连接被删除,则必须保留之前存在的历史信息。如果连接状态发生变化,则必须保留旧状态的历史信息。

我需要生成的一些报告是:

  1. A中所有(现在)未连接到B的所有元素的列表。
  2. A中所有元素的列表,这些元素连接到B中具有特定状态的至少一个元素。
  3. 曾经连接但不再连接的所有A-B对的列表。
  4. 所有A-B连接的列表,其中A的最后更改时间是在连接时间之后。
  5. 所有A-B连接的计数,其中A的最后更改时间是按状态分组的连接时间之后。
  6. 我考虑过简单地将A_B.is_current布尔字段添加到连接表中。删除连接后,我只需将is_current设置为false。状态更改时,我将旧记录的is_current设置为false,并添加具有新状态的新记录。

    对类似的先前提出的问题的回答经常声称“is_current”是糟糕的设计,应该有更好的解决方案。以前的解决方案谈到了单表中记录的修改而不是它们之间的关系。

    使用is_current列来跟踪多对多连接的历史记录是错误的吗?如果错了可能会导致什么问题?什么是更好的解决方案?

2 个答案:

答案 0 :(得分:1)

...通常

  • 有2个额外的列:ValidFromDateTimeValidToDateTime
  • 主键是A_id, B_id, ValidFromDateTime
  • ValidToDateTime可以是NULL或sentinel值(例如99991231

当新修订发生时,您填充“当前行”的ValidToDateTime并为ValidFromDateTime添加具有相同日期时间值的新行。或者,如果这是您的业务规则,则设置ValidToDateTime。

这为您提供任何时间点的状态等(或缺少)

您的查询非常简单

  1. 不存在于A_ID
  2. A_ID上的EXISTS
  3. 使用ValidToDateTime NOT_(无当前行)
  4. 在A_ID上存在
  5. A_ID上的EXISTS也比较ValidToDateTime和last_change_time
  6. LEFT JOIN(与4相同的条件)与聚合

答案 1 :(得分:0)

我使用is_current标志看到的主要问题是,一旦它们变得不是最新的,就无法确定哪些记录是最新的。我通常会添加一个日期字段,表示当前的开始日期。然后你的查询通常会抓住最新日期的行。