是否应该做一个中介table来解决查询中加入6个table的问题?

Should I make an intermediary table to solve the problem of joining 6 tables in a query?

我正在尝试制作一个与产品的生产和使用相关的数据库。生产涉及 3 个不同的步骤,每个步骤都有一个批号。我希望能够查看最终产品并编写查询以从步骤 4 及以上(使用产品的步骤)中查找 enz_name(步骤 0)。

图片中的蓝色部分 enz_name 和前两个步骤的批号相同的东西可以被视为两个不同的最终产品,因为它在最后一次生产时被拆分为 2 个不同的批次步骤.

我的objective:能够查看来自第 4 步及以上步骤的数据(来自使用最终产品的数据)并能够追踪 enz_name 的相关最终产品。

我的问题:我现在设置的方式是我必须加入 tables 从第 4 步到第 3 步,第 3 步到第 2 步,第 2 步到第 1 步,最后第 1 步到构造(第 0 步)。这么多步骤似乎很不方便。而且我基本上会要求 Oracle 搜索我的 table 的一半以上以获得答案。这是糟糕的做法和糟糕的设计吗?

我正在考虑的可能解决方案:

  1. 我想我可以用 enz_name 做一个中介 table 和 construct_id。但这并不能真正解决看问题 在 CELL tables 并且想知道 enz_name 因为我是 仍然需要经过 CHAR_ENZ、PURIFIED_ENZ、PRODUCED、CONSTRUCT 去中介table。我是否应该制作第二个中介 table 然后包含 construct_id、g_batch、p_batch 和 char_id?真的很蠢吗?

  2. 我可以将 FK construct_id 列添加到引用构造 table 的 char_enz table(生产的第 3 步)(步骤 0)。这似乎是最明显的解决方案,但有更好的方法吗?这是一个好的解决方案吗?

I could just add a FK construct_id column to the char_enz table

如您所知,这称为“非规范化”。它有一些问题。

  1. 您正在存储相同信息的多个副本。也就是说,我可以在 CHAR_ENZ 中查找酶名称或进行 6 table 连接。额外的存储空间很浪费(但实际上,谁在乎呢?)而且现在还可能出现不一致。俗话说:“有手表的人知道现在几点;有两块手表的人永远不确定”。

  2. 这使更新变得复杂。如果你想更新一个批次的酶名称,而不是仅仅更新,比如 PRODUCED.CONSTRUCT_ID,现在你还需要记住更新 CHAR_ENZ 中的所有酶名称。

非规范化不一定是魔鬼,但你应该只使用它来避免更严重的问题。 6 table 连接可能不是一个“更糟糕”的问题,足以证明它的合理性(在我看来很明显,细节很少)。

事实上,就我个人而言,我可能会选择 6 table 连接。您可以考虑在物理数据库设计期间将 PRODUCEDPURIFIED_ENZCHAR_ENZ table 放置在一个集群中。这应该最大限度地减少性能影响。也可以做一个view来封装join逻辑

如果要反规范化,可以选择“一路”不反规范化。也就是说,例如,您可以使用复合键来进行非规范化排序,但仍然受益于数据完整性约束。例如,

PURIFIED_ENZ ==> 主键(G_BATCH, P_BATCH) CHAR_ENZ ==> 主键 (G_BATCH, P_BATCH, CHAR_ID)

这也违反了第三范式,如果你想报警。但这使得 CHAR_ENZ 行和“非规范化”G_BATCH 列之间不可能存在不匹配。您可以使用 G_BATCH 来减少获取酶名称所需的连接大小。

关于您的数据模型,让我担心的最后一件事是它似乎假设并要求生产的第 1-3 步始终相同。技术变化;客户要求发生变化。我对微生物学知之甚少,但通常我想建立一个假设更少的数据模型。您可以通过稍微抽象批处理步骤来做到这一点。