在外键字段的两个表之间进行循环引用是否可以接受?
如果没有,如何避免这些情况?
如果是这样,如何插入数据?
以下是(在我看来)可以接受循环引用的示例:
CREATE TABLE Account
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Contact
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50),
AccountID INT FOREIGN KEY REFERENCES Account(ID)
)
ALTER TABLE Account ADD PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)
由于您为外键使用可为空的字段,因此您实际上可以构建一个按照您设想的方式正常工作的系统。为了将行插入到 Accounts 表中,您需要在 Contacts 表中存在一行,除非您允许使用 null PrimaryContactID 插入到 Accounts 中。为了在没有 Account 行的情况下创建联系人行,您必须允许 Contacts 表中的 AccountID 列可以为空。这允许帐户没有联系人,并允许联系人没有帐户。也许这是可取的,也许不是。
话虽如此,我个人的偏好是具有以下设置:
这提供了以下能力:
IX_AccountsContactsXRef_Primary
该索引包含一个过滤器,因此它仅适用于支持它们的平台。由于该索引是使用UNIQUE
选项指定的,因此每个帐户只能有一个主要联系人。例如,如果您想显示所有联系人的列表,其中有一列表示“主要”状态,在每个帐户的列表顶部显示主要联系人,您可以执行以下操作:
过滤索引可防止每个帐户插入多个主要联系人,同时提供返回主要联系人列表的快速方法。可以很容易地想象另一列,
IsActive
使用非唯一过滤索引来维护每个帐户的联系人历史记录,即使在该联系人不再与该帐户关联之后:不,循环外键引用是不可接受的。不仅因为如果不不断删除和重新创建约束就不可能插入数据。但因为它是我能想到的任何领域的根本缺陷模型。在您的示例中,我想不出Account 和Contact 之间的关系不是NN 的任何域,需要一个带有FK 引用的联结表返回Account 和Contact。
您可以让您的外部对象指向主要联系人,而不是客户。您的数据将如下所示: