Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有重叠子表的SQL子类型_Sql_Database_Database Design_Sql Server 2012 - Fatal编程技术网

具有重叠子表的SQL子类型

具有重叠子表的SQL子类型,sql,database,database-design,sql-server-2012,Sql,Database,Database Design,Sql Server 2012,考虑上面的问题,“CommonChild”实体可以是子类型a或B的子类型,但不能是C的子类型。我如何在关系[SQL]数据库中设计物理模型 理想情况下,解决方案将允许 用于识别CommonChild及其相关子类型之间的关系 一对一的关系。 可能的解决方案 将附加子类型添加到超级类型,并将子类型A和B移动到新子类型下。然后,CommonChild可以对新创建的子类型具有FK约束。适用于上述情况,但如果添加了与子类型a和C(而非B)有关系的附加实体,则不适用 在CommonChild和超类型之间添加

考虑上面的问题,“CommonChild”实体可以是子类型a或B的子类型,但不能是C的子类型。我如何在关系[SQL]数据库中设计物理模型

理想情况下,解决方案将允许

  • 用于识别CommonChild及其相关子类型之间的关系
  • 一对一的关系。
  • 可能的解决方案
  • 将附加子类型添加到超级类型,并将子类型A和B移动到新子类型下。然后,CommonChild可以对新创建的子类型具有FK约束。适用于上述情况,但如果添加了与子类型a和C(而非B)有关系的附加实体,则不适用

  • 在CommonChild和超类型之间添加FK约束。在允许新元组进入CommonChild之前,对超级类型的鉴别器使用触发器或检查约束(w/UDF)。看起来很直截了当,但现在CommonChild几乎像是新的子类型本身(事实并非如此)

  • 我的模型根本上是有缺陷的。改造和问题应该消失

  • 我正在寻找其他可能的解决方案,或者确认我已经提出的上述解决方案之一

    谢谢


    编辑

    我将实现Branko Dimitrijevic提供的专用外键解决方案(请参阅接受的答案)

    在这种情况下,我将做一些轻微的修改,如下所示:

  • 超级类型、子类型和“CommonChild”都具有相同的PKs和
  • PKs为3柱复合材料
  • 修改的目的是创建一个中间表,其唯一作用是在子类型和“CommonChild”(Dimitrijevic提供的确切模型减去“CommonChild”属性)之间强制执行排他FK约束。CommonChild的PK将对中间表具有普通FK约束


    这将防止“CommonChild”具有2组3列复合FK。另外,由于标识关系是从超级类型到“CommonChild”进行维护的,[read]查询可以有效地完全忽略中间表

    看起来您需要以下变量:

    这里有几点需要注意:

    • 有两个NULL able外键
    • 有一个检查允许这些FK中只有一个不为空
    • 有一个计算列
      Id
      ,它等于一个FK(当前为非空的),这也是一个主键。这可确保:
      • 一个父项不能有多个子项
      • “孙子”表可以直接从其FK引用
        CommonChild.Id
        SuperType.Id
        被有效地向下移动
      • 我们不必处理可空的唯一约束,这在MS SQL Server中是有问题的(见下文)

    DBMS不可知的做类似事情的方法是

    CREATE TABLE CommonChild (
        Id int PRIMARY KEY,
        SubTypeAId int UNIQUE REFERENCES SubTypeA (SuperId),
        SubTypeBId int UNIQUE REFERENCES SubTypeB (SuperId),
        Attr6 varchar,
        CHECK (
            (SubTypeAId IS NOT NULL AND SubTypeAId = Id AND SubTypeBId IS NULL)
            OR (SubTypeAId IS NULL AND SubTypeBId IS NOT NULL AND SubTypeBId = Id)
        )
    )
    

    不幸的是,MS SQL Server不允许包含多个NULL的唯一列,这在大多数DBMS中是不允许的。但是,如果您不想直接引用
    subsubsipaid
    subsibid
    ,您可以省略唯一约束。

    想知道我在这里遗漏了什么吗

    诚然,没有具体问题的措辞是很难的,但事情确实有点颠倒了



    在SQL Server中可以使用筛选索引来强制执行忽略
    null
    s@MartinSmith是的,但这将是一个索引,而不是唯一的约束,因此它不能(例如)被外键引用,它的违规行为将以不同的方式报告给客户端(如果这很重要的话)。此外,有一种哲学观点反对混合物理和逻辑概念。SQL Server允许FKs引用唯一的索引。但它不允许唯一的筛选索引。对于使用COALESCE的计算主键语法,+1…我已经遇到过几次相同的场景,虽然我找到了两个可为null的FK和CHECK约束,但我从未找到如何以这种方式实现主键。现在看起来很明显!优雅的我曾考虑过添加一个额外的层次结构,但在这种特殊情况下,再加上限制A&B和A&C有一个共同的孩子,这是没有意义的。实际上,我的“CommonChild”实体应该是它自己的独立实体。各种子类型应通过FK引用或关联表引用CommonChild。这是一个70年代后期大型机中非常不规范(且较差)的数据模型的中间规范化模型。
    CREATE TABLE CommonChild (
        Id int PRIMARY KEY,
        SubTypeAId int UNIQUE REFERENCES SubTypeA (SuperId),
        SubTypeBId int UNIQUE REFERENCES SubTypeB (SuperId),
        Attr6 varchar,
        CHECK (
            (SubTypeAId IS NOT NULL AND SubTypeAId = Id AND SubTypeBId IS NULL)
            OR (SubTypeAId IS NULL AND SubTypeBId IS NOT NULL AND SubTypeBId = Id)
        )
    )