我应该创建一个可以为null的外键还是创建一个新表?

时间:2016-02-11 07:37:30

标签: database database-design foreign-keys relational-database database-schema

关于如何设计数据库,我有一个小问题。我有一个用于动物收容所的桌犬,我有一个桌主。在桌子上的狗,所有和曾经在庇护所的狗都被放入。现在我想在餐桌狗和餐桌老板之间建立关系。

问题是,在这个例子中并非所有的狗都有一个主人,并且由于主人可以有一只以上的狗,所以可能的外键应该放在桌上的狗(一只狗不能有一个以上的主人,至少不在庇护所的管理中)。但是,如果我这样做,一些狗(庇护所中的狗)将作为外键使用null。阅读其他一些主题告诉我这是允许的。 (或者我可能已经阅读了一些错误的主题)

然而,另一种可能性是在两个表之间放置一个表 - 例如'dogswithowners' - 并且如果狗拥有所有者,则将两个表的主键放在那里。

现在我的问题是(正如你可能已经猜到的)这两种方法最好的方法是什么?为什么?

6 个答案:

答案 0 :(得分:4)

符合关系模型原则的唯一解决方案是额外表格。

此外,很难想象你将如何找到任何速度太慢的硬件,以至于在开始查询时性能的差异会很明显。毕竟,它不是一项关键任务,每秒数万次交易应用,是吗?

答案 1 :(得分:4)

我同意Philip和Erwin的观点,认为最灵活,最灵活的设计是创造一张新桌子。

基于空的方法的另一个问题是,不同的软件产品不同意SQL的可空外键如何工作。甚至许多IT专业人员也不能正确理解它们,因此普通用户更不可能理解它。

答案 2 :(得分:2)

可以为空的外键是一种典型的解决方案。

最简单的就是拥有另一张拥有者和狗的桌子,所有者的外键和带有狗栏UNIQUE NOT NULL的狗桌。然后,如果您只想要所有者或拥有的狗,您不必在查询中涉及IS NOT NULL,并且DBMS不需要在所有所有者和狗中访问它们。 NULL可以简化像这样的某些情况,但与拥有单独的表相比,它们也很复杂,只需要在需要数据时加入。

但是,如果狗有可能拥有多个所有者,那么您可能还需要额外的表格:许多关系没有UNIQUE NOT NULL列和列对所有者 - 狗UNIQUE NOT NULL而不是。如果事情发生变化,你总是可以从一个UNIQUE NOT NULL开始,然后移动到另一个。

答案 3 :(得分:1)

在新闻组的旧时代,我们有一个名叫-CELKO的人,他会弹出并说,"有一个设计经验法则说关系表应该模拟一个实体或一个关系实体,但从不两者兼有。"不是非常正式,但在我看来这是一个很好的经验法则。

'所有者' (人)真的是狗的属性?在我看来,你更希望模仿这种关系'所有权'在一个人和一个狗之间。

另一个有用的经验法则是避免SQL空值!三值逻辑让大多数用户和程序员感到困惑,整个SQL标准中的null行为不一致(正如sqlvogel指出的那样)SQL DBMS供应商以不同的方式实现事物。对缺失数据进行建模的最佳方法是在relvar中省略元组(也就是说,不要在表中插入任何内容!)。例如,Fido中包含Dog,但DogOwnership中已忽略该Fido,然后根据封闭世界假设{{1}}遗憾地没有所有者。

所有这些都指向拥有两个表并且没有可空列。

答案 4 :(得分:0)

用于外键关系的可空列完全有效,并用于与您完全相同的场景。

添加另一个表来连接所有者表和狗表将创建多对多关系,除非在其中一个列(在您的情况下为狗)上创建唯一约束。

由于你描述了一对多的关系,我会选择第一个选项,这意味着有一个可以为空的外键,因为我发现它更具可读性。

答案 5 :(得分:0)

我不会做任何额外的桌子。如果由于某种原因没有允许空值(这是一个很好的问题原因) - 我会,并且我知道一些解决方案也会这样做,而不是null一些值,这不是一个真正的关键。例如NOT_SET左右。

希望有所帮助