1

我无法为以下问题提出解决方案。

假设我有一个如下所示的数据库:

问题表

Id | Details | CreateDate | ClosedDate

发行说明表

Id | ObjectId | Notes | NoteDate

问题分配表

Id | ObjectId | AssignedToId| AssignedDate

我想允许将一个问题链接到另一个问题。我考虑在问题表中添加一个名为 ParentIssueId 的列,这将使我能够链接问题,但我预见如果我完成此实现,问题表中会发生循环引用。有没有更好的方法来做到这一点,如果有,怎么做?

谢谢

4

3 回答 3

1

您可以添加如下所示的连接/链接表:

问题链接

IssueId | LinkedIssueId

其中两列都是问题表的外键。

这将允许您任意链接问题,并允许将单个问题链接到具有父样式关系的其他几个问题。

您需要在两列上放置一个唯一索引,这样您就不会得到重复的数据,并且还要进行测试以确保没有这样的条件:

IssueId & LinkedIssueId = LinkedIssueId & IssueId

(这将导致逻辑​​重复)

看这里:http ://en.wikipedia.org/wiki/Junction_table 唯一的区别是Junction 表指向同一个表来创建一对多的关系。

于 2010-04-29T17:50:05.000 回答
1

创建表:

LinkedIssues
IssueIDa    pk composite primary key, fk to Issue table
IssueIDb    pk composite primary key, fk to Issue table

PK 将保留一些重复项,但会创建一个检查约束:IssueIDa<IssueIDb因此您最终不会得到如下重复项:

row 1 IssueIDa=123
      IssueIDb=987

row 2 IssueIDa=987
      IssueIDb=123

但是要防止像这样的圆圈:

row 1 IssueIDa=123
      IssueIDb=987

row 2 IssueIDa=987
      IssueIDb=456

row 3 IssueIDa=456
      IssueIDb=123

你需要一个触发器来解决链,并在一个圆圈上失败。使用递归 CTE 将是检测这个圆圈的最佳选择。

于 2010-04-29T17:56:23.677 回答
0

如果一个问题可能与另一个“父”问题有关,那么在表中有一个“ParentId”列就可以了(NULL 表示没有父)。如果一个问题可能与多个其他问题相关,则需要一个新的“多对多”(或“链接”)表。

任何一种情况下,检查和防止循环引用(特别是当“循环”包含三个或更多问题时)都会很棘手。您可以在 UPDATE 期间通过基于 CTE 的更新来检查圆,该 CTE 检查循环引用并在找到任何更新时失败,或者您可以在首先检查圆的存储过程中进行更新,并且仅在以下情况下发布更新检查通过。(当然,你必须担心并发问题——如果数据在你的检查和更新之间发生变化——这使得基于 CTE 的更新更可取,如果更复杂的话。)

于 2010-04-29T18:33:34.620 回答