约束,3个FK,一个空,SQL Server 2012,仅限DB理论

时间:2017-07-26 00:25:41

标签: sql-server database-design constraints

请在向下投票之前阅读我的免责声明

我有下表。

Inventory (InventoryID (PK), LocationID (FK), ProductID (FK), BookID (FK), Quantity)

我当前的约束强制要求BookIDProductID对于给定的行不能为空,并且LocationID不能为空。

我想要一个强制执行以下操作的约束:LocationID + ProductID + BookID必须是唯一的。换句话说,我不希望书籍或产品在同一地点出现两次。

要明确的是,对于任何记录,ProductIDBookID可以为空,但不能同时为空,LocationID不能为空。

免责声明:

  1. 这个问题完全基于个人的好奇心。结果不会以任何方式影响评分作业。我很好奇

  2. 任何回答这个问题的人都应该有足够的经验来承担排除的细节

  3. 我只是在寻找可能的约束或类似解决方案。我不是在寻找返工

1 个答案:

答案 0 :(得分:1)

在SQL Server中,唯一约束/索引仅允许一个NULL值。所以,我认为你可以用过滤索引做你想做的事情:

create unique index unq_inventory_LocationID_ProductID_BookID
    on inventory(LocationID, ProductID, BookID)
    where LocationID is not null and ProductID is not null and BookID is not null;

您的check约束应该照顾其他条件。

编辑:

啊,我明白了。您需要两个独特的约束:

create unique index unq_inventory_LocationID_ProductID
    on inventory(LocationID, ProductID)
    where LocationID is not null and ProductID is not null;

create unique index unq_inventory_LocationID_BookID
    on inventory(LocationID, BookID)
    where LocationID is not null and BookID is not null;

或者,如果您更喜欢一个唯一索引,则可以使用计算列:

alter table inventory add BookId_or_ProductId as (coalesce(BookId, ProductId));

create unique index unq_inventory_LocationID_BookID_ProductId
    on inventory(LocationID, BookId_or_ProductId);