唯一子行的SQL约束

唯一子行的SQL约束,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我有一个家长桌上的人。和3个子表PersonA、PersonB和PersonC Person - ID int primary key not null, name varchar(50) null PersonA - ID int primary key not null references Person(ID), fname, lname, zip etc. PersonB - ID int primary key not null references Person(ID), fname

我有一个家长桌上的人。和3个子表PersonA、PersonB和PersonC

Person - ID int primary key not null, name varchar(50) null
PersonA - ID int primary key not null references Person(ID), fname, lname, zip etc.
PersonB - ID int primary key not null references Person(ID), fname, lname, zip etc.
PersonC - ID int primary key not null references Person(ID), fname, lname, zip etc.

我需要建立一个约束,确保一个人只属于这三个人中的一个人。例如,如果我在Person中有一行是234,JohnSmith和我当前的设计,我可以在PersonA、PersonB和PersonC中有相同的234。我的目标是只在三个chilt表中的一个表中使用234。

处理此问题的一种方法是在
Person
表中使用三个外键引用,并带有一个约束:

PersonAID int references PersonA(ID),
PersonBID int references PersonB(ID),
PersonCID int references PersonC(ID),
check ((PersonAID is not null and PersonBID is null and PersonCID is null) or
       (PersonBID is not null and PersonCID is null and PersonAID is null) or
       (PersonCID is not null and PersonAID is null and PersonBID is null)
      )
注意:如果要允许这三个值都
NULL

check ((PersonAID is not null and PersonBID is null and PersonCID is null) or
       (PersonBID is not null and PersonCID is null and PersonAID is null) or
       (PersonCID is not null and PersonAID is null and PersonBID is null) or
       (PersonAID is null and PersonBID is null and PersonCID is null)
      )

如果这样做,则可能不需要从每个子表到主表的引用。

可以使用插入触发器添加约束,因此,在插入行时,请检查没有其他表具有相同的行id。或者,创建一个映射表,该表已使用主id和另一个引用子表id的列id引用主person表。在主表id上设置主键。

是否尝试创建三个子表的并集视图,然后在此视图上创建唯一索引?退房


我认为你需要回顾一下你的模型。处理人员类型的四个表?我建议你研究规范化。我同意,这有点误导。我说的是提供者、医院、护理人员等,但他们都被视为单一实体,因为他们为我们的成员服务。但无论如何,请不要把注意力集中在语义上,而是告诉我如何做到这一点。父级中的一行意味着它的一个子级中只有一行对应的行。我认为没有办法通过约束来做你想做的事情。实现这一点的最好方法是使用触发器。谢谢大家。无法投票,因为我需要更多的声望点。这将使主要人物表失去其设计。按照我的解决方案中的建议创建映射表,这将单独保留数据并使其正常化,但这只是一个查看数据的视图,在插入行时,它不像约束那样工作。
Create View Persons
as

Select ID From PersonA    
union    
Select ID From PersonB    
union    
Select ID From PersonC


--Create an index on the view.
CREATE UNIQUE CLUSTERED INDEX IDX_V1 
    ON Persons (ID);