请考虑以下情况。宠物主人可能有多只猫,也可能有多只狗。有些狗与同一所有者中的一些猫相关(即他们打架:-))。
以下关系设计并未强加此限制,因为不同所有者的猫和狗可能相关。有没有办法通过关系设计强加这种限制?
答案 0 :(得分:1)
您需要使用识别关系将所有者的PK迁移到菱形依赖的“边”和“底部”:
由于CatDog.OwnerId
只是一个字段,因此无法识别每行的多个所有者,并且因为它是针对这两种动物的FK,所以这一个所有者必须匹配猫和狗的所有者。
换句话说,猫只能与同一所有者的狗有关。
正如您所看到的,猫和狗的识别方式与您的预期不同。猫由其所有者识别,并通过其CatNo
与同一所有者的其他猫区分开来。同样适合狗。
如果您需要一个“更简单”的密钥,您可以随时添加一个代理密钥,或者,您可以通过“滥用”UNIQUE约束完全消除CatNo
和DogNo
,仅用于迁移OwnerId
:
(U1
表示UNIQUE约束。)
现在你可以更简洁地识别动物,但是有一个缺点:从强制执行唯一性的角度看,UNIQUE约束完全是多余的。它是PK的超级集合,PK正在强制执行其独特性。 UNIQUE约束的唯一目的是使CatDog.OwnerId
能够引用Cat.OwnerId
(和Dog.OwnerId
) - 大多数DBMS要求外键的父端点为密钥。
某些DBMS(Oracle)将允许您仅使用一个索引来强制执行PK和UNIQUE约束,但大多数不会。每个附加索引都会损害插入/更新/删除性能。