2011-08-22 87 views
0

我的问题是关于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. 在一个所有元素,这些元素没有(现在)连接到B的列表。
  2. A中所有元素的列表,它们与B中至少一个元素连接并处于特定状态。
  3. 曾经连接但不再连接的所有A-B对的列表。
  4. A的最后更改时间在连接时间之后的所有A-B连接的列表。
  5. 计算A的最后更改时间在按状态分组的连接时间之后的所有A-B连接。

我认为只需在连接表中添加A_B.is_current布尔型字段即可。当连接被删除时,我只需将is_current设置为false即可。当状态发生变化时,我将旧记录的is_current设置为false,并添加一个具有新状态的新记录。

回答类似的以前问的问题往往声称“is_current”是不好的设计,应该有更好的解决方案。以前的解决方案谈论单个表中记录的修改,而不是它们之间的关系。

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

回答

1

通常...

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

当新版本发生时,您填充“当前行”的ValidToDateTime并添加一个新行ValidFromDateTime的日期时间值相同。或者,如果这是您的业务规则,请设置ValidToDateTime。

这给你的时间陈述等(或缺乏)的任何点

你的查询都是那么很简单

  1. NOT EXISTS上A_ID
  2. 存在于A_ID
  3. 存在于带有ValidToDateTime的A_ID NOT NULL(无当前行)
  4. A_ID上的EXISTS也将比较ValidToDateTime和last_change_time
  5. 与合计的左加入(条件与4相同)
+0

这听起来合乎逻辑。用空记录ValidTo是当前记录,当我更改关系状态时,我只需用当前时间更新旧记录。 – Muxecoid

0

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

+0

我已经有connected_since_time字段。问题是,在某些报告中,我需要输出所有连接对的列表,在这种情况下,is_current感觉像是比按时间排序和获取最大值更合理的方法。只有修订时间的另一个问题是删除连接。 – Muxecoid

+0

考虑到删除,引入ValidTo字段的gbn响应应该解决问题。只用一个is_current字段,就不可能知道某个特定时间点的有效性。 – NickHeidke