CREATE TABLE Parent ( ParentID int NOT NULL PRIMARY KEY,
ParentName varchar(50) NULL )
CREATE TABLE Child ( ChildID int NOT NULL PRIMARY KEY,
ParentID int NOT NULL REFERENCES Parent (ParentID),
ChildName varchar(50) NULL,
IsFavorite BIT NOT NULL )
第一个愿望是想防止无子父母的情况发生。显然,当第一次创建该对时,父对象将没有子对象,我不想阻止插入本身;但我想彻底禁止删除最后一个孩子。(出于商业原因,Parents 永远不会被删除。)
作为第二个愿望,我需要阻止多个 IsFavorite=1 的 Child,我知道我可以使用过滤的唯一索引来做到这一点。我还想劝阻没有 IsFavorite=1 的子项——即,如果这是其父项的唯一子项,则不允许设置 IsFavorite=0。(从应用程序方面来看,对于第一个孩子,插入通常应该使用 IsFavorite=1 正确完成;但我不希望数据库干扰它。)
我确定我不是第一个有这些愿望的人,但我在 dba 或 stackoverflow 上找不到匹配的问题。如果这是一个骗局,一定要把它标记为骗局,并指出我需要去的地方。
您可以在 Parent 上创建 (ParentId,FavoriteChildId) FK 并获得其中的大部分。然而,在 SQL Server 中,没有实用的方法来建立所需的关系,因此您必须允许父项没有最喜欢的子项,否则您将无法在不禁用 FK 的情况下插入新的父项。
您可以添加触发器以防止以后将 FavoriteChildId 设置为 null,但至少在 Parent 有一个 Child 的情况下必须允许它,否则将无法删除该 Child。所以我不确定是否值得为 Trigger 烦恼。例如:
AFTER
使用过滤的唯一索引和几个触发器可能最容易实现这些(有些不寻常的)要求:表和索引
删除触发器
更新触发器
和往常一样,如果主键不可变,更新触发器只会正确处理所有多行更新。实现此目的的最简单方法是创建
ChildID
标识列。