所有现在和曾经在动物收容所的狗都被放入桌犬中。
现在我想要桌狗和主人之间的关系。
并非所有的狗都有主人,一个主人可以拥有不止一只狗。一只狗不能有多个主人。
外键可以放在桌狗中。但如果我这样做,收容所里的狗的外键将为 null。
另一种可能性是将表 dogswithowners 放在两个表之间,如果狗有主人,则将两个表的主键都放在其中。
这两者中最好的是什么?为什么?
唯一符合关系模型原则的解决方案是额外的表。
此外,很难想象您将如何找到如此慢的硬件,以至于当您开始查询时性能差异会很明显。 毕竟,它不是一个每秒处理数万笔事务的关键任务应用程序,不是吗?
我同意 Philip 和 Erwin 的观点,最合理、最灵活的设计是创建一张新桌子。
基于 null 的方法的另一个问题是,不同的软件产品对于 SQL 的可为 null 的外键如何工作存在分歧。甚至很多 IT 专业人士都无法正确理解它们,因此普通用户更不可能理解它。
可空外键是一个典型的解决方案。
最直接的方法是拥有另一张主人和狗的表,并使用主人和狗表的外键以及狗列 UNIQUE NOT NULL。然后,如果您只想要所有者或拥有的狗,则不必在查询中包含 IS NOT NULL,并且 DBMS 不需要在所有所有者和狗之间访问它们。 NULL 可以简化像这样的某些情况,但与拥有单独的表并在需要数据时才加入相比,它们也变得复杂。
但是,如果一只狗可能有多个主人,那么您可能需要额外的表,因为没有 UNIQUE NOT NULL 列和列对所有者-狗 UNIQUE NOT NULL 的多:多关系。您始终可以从一个 UNIQUE NOT NULL 开始,然后在情况发生变化时移至另一个。
在过去的新闻组中,我们有一个叫 -CELKO- 的人,他会突然出现并说:“有一个设计经验法则,即关系表应该对实体或实体之间的关系进行建模,但不能同时对两者进行建模。 ”不是很正式,但在我看来这是一个很好的经验法则。
“主人”(人)真的是狗的属性吗?在我看来,你更像是想模拟人与狗之间的“所有权”关系。
另一个有用的经验法则是避免 SQL null!三值逻辑让大多数用户和程序员感到困惑,空行为在整个 SQL 标准中不一致,并且(正如 sqlvogel 指出的)SQL DBMS 供应商以不同的方式实现事物。对缺失数据进行建模的最佳方法是在相关变量中省略元组(也就是不要在表中插入任何内容!)。例如,
Fido
包含在Dog
中,但从DogOwnership
中省略,那么根据封闭世界假设,Fido
遗憾的是没有所有者。
所有这些都表明有两个表并且没有可为空的列。
我不会做任何额外的桌子。如果由于某种原因不允许空值(这是一个很好的问题为什么) - 我会,而且我知道一些解决方案也会做同样的事情,用一些值代替空值,这不能是真正的键。例如 NOT_SET 左右。
希望有帮助
用于外键关系的可为空列是完全有效的,并且用于与您的场景完全相同的场景。
添加另一个表来连接owners表和dogs表将创建多对多关系,除非在其中一个列(在您的例子中是dogs)上创建了唯一约束。
既然您描述了一对多关系,我会选择第一个选项,这意味着有一个可以为空的外键,因为我发现它更具可读性。