外键中某些列的条件

Condition for some column in foreign key

有 table 个包含列 (Id, BId) 的 A。 BId 是 table B 的外键。B 有列 (Id, Type)。

CREATE TABLE [A] (
    [Id] INT IDENTITY CONSTRAINT [PK_A_Id] PRIMARY KEY,
    [BId] INT NOT NULL CONSTRAINT [FK_A_B] REFERENCES [B](Id) 
)
GO
CREATE TABLE [B] (
    [Id] INT IDENTITY CONSTRAINT [PK_B_Id] PRIMARY KEY,
    [Type] INT NOT NULL 
)
GO

所以,这是一个非常简单的方案,但我想为外键添加条件,如"type should be 0"。应该是这样的

CONSTRAINT [FK_A_B] REFERENCES [B](Id) WHERE [B].[Type] = 0

如何正确使用UNIQUE关键字等实现?

如果这可以使用过滤的唯一索引来完成,那就太好了。但是,SQL 服务器不允许这样做。所以这是另一个想法:

首先定义一个(冗余的)唯一约束:

CREATE TABLE [B] (
    [Id] INT IDENTITY CONSTRAINT [PK_B_Id] PRIMARY KEY,
    [Type] INT NOT NULL,
    UNIQUE (ID, Type)
)
GO

现在,我认为您不能将约束定义为:

CONSTRAINT [FK_A_B] (ID, 0) REFERENCES [B](Id, Type) 

但是,我认为您可以通过以下方式欺骗它:

_Type as 0,
CONSTRAINT [FK_A_B] (ID, _Type) REFERENCES [B](Id, Type) 

也就是说,添加一个计算列并将其用于约束。

您要实现的目标不是 FOREIGN KEY 的任务。在 FK 中,您无法在目标 table 上指定其他条件。如果你有这样的需求,通常意味着你的数据库没有规范化。看起来 table [B] 将多个数据实体存储在一个 table 中,类型列决定了它是什么实体。如果您违反规范化规则,声明完整性意味着 FK 对您不起作用。从现在开始,您必须自己控制完整性。您可以在应用程序逻辑中执行此操作或创建触发器(程序完整性)。在任何情况下,数据库中都不会有外键约束。