我有一张名为Message
的表格。每条消息都可以与Invoice
表或Rfp
表相关联,但不能同时与两者相关联。我正在努力实现这个目标的最佳方式:
一种方法是Message
表具有Invoice
和Rfp
表的外键。一个FK有效,而另一个必须为NULL。 (单表继承。)但这似乎相当尴尬。除了未使用的列之外,我还需要找到防止FK既可以使用也可以同时使用NULL的情况的方法。对于每条消息都需要重复这一过程。
另一种方法是创建连接表。在这种情况下,我的Message
表将具有到加入表的FK,并且Invoice
和Rfp
表也将具有到加入表的FK。但是,这里的问题是,给定对连接表的引用,找到相关的Invoice
或Rfp
表是很尴尬的,因为我不知道哪个包含FK。所以,在这里,我需要采用其他步骤来了解如何找到相关的表,例如添加一列来表示哪个表是相关的,为此很难创建约束。
最后,我可以创建两种类型的Message
表。这解决了上面描述的问题,但这会给我们的应用程序带来问题,因为我们在需要添加消息而不知道它们是什么类型的地方有逻辑。 (我们只能在相关表格中有一个FK。)
有人可以在这里提供一些提示。这些方式都不是理想的,但也许在我们两者之间选择时我没有考虑过。或者也许总有一种更好的方法。
答案 0 :(得分:2)
在选项1中,您可以使用检查约束来确保只设置一个FK ...
CREATE TABLE [dbo].[Rfp] (Id int IDENTITY(1,1) NOT NULL, PRIMARY KEY CLUSTERED (Id))
CREATE TABLE [dbo].[Invoice] (Id int IDENTITY(1,1) NOT NULL, PRIMARY KEY CLUSTERED (Id))
CREATE TABLE dbo.[Message] (Id int IDENTITY(1,1) NOT NULL, RfpId int, InvoiceId int,
PRIMARY KEY CLUSTERED (Id),
FOREIGN KEY (RfpId) REFERENCES [dbo].[Rfp] (Id),
FOREIGN KEY (InvoiceId) REFERENCES [dbo].[Invoice] (Id),
)
ALTER TABLE dbo.[Message]
ADD CONSTRAINT CK_FK CHECK ( (RfpId IS NULL AND InvoiceId IS NOT NULL)
OR (RfpId IS NOT NULL AND InvoiceId IS NULL));