关系设计 - 一张表,两个外键或两张表,各一个外键

cri*_*vin 6 database-design sql-server relational-theory design-pattern

在以下场景中寻找与优化设计相关的一些建议。

  1. 有一个 Cases 表(代表库存的情况)
  2. 有一个 LocationInventory 表(代表有库存的位置)
  3. 然后我有一个或多个 InventoryNeed 表(这是问题的关键),需要考虑案例和位置。

选项A:

一张表有 2 个外键列,其中将填充一个且仅一个外键。

表:库存需求

  1. 案例 ID (FK)
  2. 位置库存 ID (FK)
  3. 所需数量

在这种情况下,CaseId 或 LocationInventoryId 将为 null,而另一个已填充。

选项B:

每种需求类型有两个表,经常通过 UNION 来获取摘要数据。

表:库存需求案例

  1. 案例 ID (FK)
  2. 所需数量

表:库存需求地点

  1. 位置库存 ID (FK)
  2. 所需数量

选项C:

一张没有参照完整性的表。

表:库存需求案例

  1. NeedType(案例或位置的值)
  2. NeedId(表示基于 NeedType 的 Case 或 LocationInventory 的主键)。
  3. 所需数量

最终获胜者是?我可能会将范围缩小为 A 或 B 以确保数据完整性......但不确定哪个是最好的。或者也许有一个选项 D(例如创建具有公共列的基表......)

更新的场景

当我昨晚发布此内容时,我只考虑下游,但也存在对这些相同表的上游依赖关系。我画了一些图,希望能更好地解释它。随着这个出现,选项 B 开始爆炸所涉及的表的数量,在阅读了这个 SE 答案之后……我现在更倾向于 A。

下面的图片。然后红色代表库存需求,绿色代表满足这些需求的库存来源。黄色是当前的问题......如何有效地连接红色和绿色。

选项 A 图片 - 有更多解释和背景 选项A

选项 B - 为清楚起见删除了上下文 选项 B - 继承

小智 2

在大多数情况下我肯定会推荐 B。A 和 C 都留下了很大的不一致空间。强制执行两列中的某一列NOT NULL(对于情况 A)是相当痛苦的。如果您需要唯一性,则强制一个列要么是唯一值,要么是NULL,另一列也是唯一值,要么NULLNULL,这是一个巨大的痛苦。

正如您所认识到的,C 也错过了一些一致性检查。

我不太明白你想要表达的信息是什么。但对我来说通常是有意义的,如果您试图使一个表引用两个不同的其他表之一,那么第一个表中的信息实际上由两种不同的事物组成。

还应该考虑到,执行UNION, 比进行大量以下形式的查询更容易且更具可读性:

SELECT *
FROM InventoryNeed
WHERE CaseId IS NOT NULL
AND LocationInventoryId IS NULL
Run Code Online (Sandbox Code Playgroud)

(这个查询本身看起来并不算太糟糕,但是您将在 JOIN 等中使用单个表名的任何地方使用它)。