Eri*_* W. 5 sql database database-design sql-server-2012
考虑上面的问题,其中'CommonChild'实体可以是子类型A或B的子类,但不是C.如何在关系[SQL]数据库中设计物理模型?
理想情况下,解决方案将允许......
向超类型添加其他子类型,并在新子类型下移动子类型A和B. 然后,CommonChild可以对新创建的子类型具有FK约束.适用于上述情况,但如果添加的附加实体可能与子类型A和C有关,但不是B.
在CommonChild和SuperType之间添加FK约束.在允许新元组进入CommonChild之前,对超类型的鉴别器使用触发器或检查约束(w/UDF).看起来很直接,但现在CommonChild几乎看起来像新的子类型(它不是).
我的模型存在根本缺陷.重塑和问题应该消失.
我正在寻找其他可能的解决方案或确认我已经提出的上述解决方案之一.
谢谢!
编辑
我将实施Branko Dimitrijevic提供的独家外键解决方案(见接受的答案).
我将在这种情况下稍作修改:
修改是创建一个中间表,其唯一的作用是强制子类型和"CommonChild"之间的独占FK约束(Dimitrijevic提供的精确模型减去"CommonChild"属性).CommonChild的PK将对中间表具有正常的FK约束.
这将阻止"CommonChild"具有2组3列复合FK.另外,由于识别关系从超类型维护到"CommonChild",[读取]查询可以完全有效地忽略中间表.
看起来您需要一种专有外键的变体:
CREATE TABLE CommonChild (
Id AS COALESCE(SubTypeAId, SubTypeBId) PERSISTED PRIMARY KEY,
SubTypeAId int REFERENCES SubTypeA (SuperId),
SubTypeBId int REFERENCES SubTypeB (SuperId),
Attr6 varchar,
CHECK (
(SubTypeAId IS NOT NULL AND SubTypeBId IS NULL)
OR (SubTypeAId IS NULL AND SubTypeBId IS NOT NULL)
)
);
Run Code Online (Sandbox Code Playgroud)
这里有几点需要注意:
Id
等于 FK 之一(以当前非 NULL 为准),它也是主键。这可以确保:
CommonChild.Id
直接从其 FK 引用。有效地SuperType.Id
一直向下传播。执行类似操作的与 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)
)
)
Run Code Online (Sandbox Code Playgroud)
不幸的是,MS SQL Server 不允许包含多个 NULL 的 UNIQUE 列,而大多数 DBMS 中并非如此。但是,如果您不想引用SubTypeAId
或SubTypeBId
不想直接引用,则可以省略 UNIQUE 约束。