我在解决以下问题时遇到问题。
假设我有一个类似于以下内容的数据库:
问题表
Id | Details | CreateDate | ClosedDate
发行备注表
Id | ObjectId | Notes | NoteDate
问题分配表
Id | ObjectId | AssignedToId| AssignedDate
我想允许将问题链接到另一个问题。 我想在Issue表中添加一个名为ParentIssueId的列,这将允许我链接问题,但我预见如果我执行此实现,则会在问题表中发生循环引用。 有没有更好的方法来做这件事,如果有,怎么做?
由于
答案 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的更新比较复杂,如果更复杂的话。)