【问题标题】:SQL constraint for unique child rows唯一子行的 SQL 约束
【发布时间】:2014-06-10 16:39:21
【问题描述】:

我有一个父表 Person。以及 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。我的目标是仅在三个子表中的一个中包含 234。

【问题讨论】:

  • 我认为您需要检查您的模型。处理人员类型的四个表?我建议你学习标准化。
  • 我同意,这有点误导。我说的是提供者、医院、护理人员等。但它们都被视为单一实体,因为它们为我们的会员提供服务。但无论如何,请不要专注于语义,而是告诉我如何做到这一点。父级中的一行表示其子级中的一个且只有一个对应行。
  • 我认为没有办法通过约束来做你想做的事,最好的方法是使用触发器。
  • 谢谢大家。无法投票,因为我需要更多的声誉点数。

标签: sql sql-server sql-server-2008 tsql


【解决方案1】:

处理此问题的一种方法是在 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)
      )

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

【讨论】:

  • 这会使主人表失去其设计。按照我的解决方案中的建议创建映射表,这将单独保存数据并进行规范化
【解决方案2】:

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

【讨论】:

    【解决方案3】:

    您是否尝试过创建三个子表的并集视图,然后在该视图上创建唯一索引?查看MSDN

    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);
    

    【讨论】:

    • 但这只是一个查看数据的视图 - 在插入行时它不像约束一样工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-01
    相关资源
    最近更新 更多