数据库设计 - 链接到没有循环引用问题的父级

时间:2010-04-29 17:32:57

标签: database-design circular-reference

我在解决以下问题时遇到问题。

假设我有一个类似于以下内容的数据库:

问题表

Id | Details | CreateDate | ClosedDate

发行备注表

Id | ObjectId | Notes | NoteDate

问题分配表

Id | ObjectId | AssignedToId| AssignedDate

我想允许将问题链接到另一个问题。 我想在Issue表中添加一个名为ParentIssueId的列,这将允许我链接问题,但我预见如果我执行此实现,则会在问题表中发生循环引用。 有没有更好的方法来做这件事,如果有,怎么做?

由于

3 个答案:

答案 0 :(得分:1)

您可以添加看起来像这样的连接/链接表:

<强> IssueLink

IssueId | LinkedIssueId

其中两列都是Issue表的外键。

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

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

IssueId & LinkedIssueId = LinkedIssueId & IssueId

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

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

答案 1 :(得分: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将是检测此圈的最佳选择。

答案 2 :(得分:0)

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

的情况下,检查和阻止循环引用(特别是当“圈子”包含三个或更多问题时)将是棘手的。您可以在UPDATE期间检查圈子,方法是在CTE上检查循环引用的更新,如果找到任何更新则更新失败,或者您可以在首先检查圈子的存储过程中更新,并且仅在发出更新时才发出更新支票通过。 (当然,你必须担心并发问题 - 如果你的检查和更新之间的数据发生了变化会怎样 - 这使得基于CTE的更新比较复杂,如果更复杂的话。)