我想建立一个数据库,把产品的生产和使用联系起来。生产包括3个不同的步骤,每个步骤都有一个批号。我希望能够查看最终产品,并编写一个查询,从步骤4和以上(使用产品的步骤)中查找enzèu名称(步骤0)。
这张图中的蓝色是如何将两个步骤中具有相同enz\u名称和批号的产品视为两个不同的最终产品的,因为在最后一个生产步骤中它被分成两个不同的批次。
我的目标是:能够查看第4步及以上的数据(使用最终产品的数据),并能够追踪相关最终产品的enz\u名称。
我的问题:我现在设置它的方式是,我必须将表从步骤4连接到步骤3,步骤3连接到步骤2,步骤2连接到步骤1,最后步骤1连接到构造(步骤0)。这么多步骤似乎不方便。基本上,我会让甲骨文搜索我一半以上的表来得到答案。那是坏习惯和坏设计吗?
我正在考虑的可能解决方案:
我想我可以用enz\u name和construct\u id创建一个中间表,但这并不能真正解决查看单元格表和想知道enz\u name的问题,因为我仍然需要通过char\u enz,purified\u enz,produced,construct来访问中间表。我是否应该创建第二个包含construct\u id、g\u batch、p\u batch和char\u id的中间表?那真的很蠢吗?
我可以只向char\u enz表(生产的步骤3)添加一个fk construct\u id列,该表引用construct表(步骤0)。这似乎是最明显的解决办法,但有更好的办法吗?这是个好办法吗?
1条答案
按热度按时间cunj1qz11#
我可以只在char\u enz表中添加一个fk construct\u id列
这就是所谓的“去规范化”,你可能知道。它带来了一些问题。
您正在存储同一信息的多个副本。也就是说,我可以往里面看
CHAR_ENZ
查找酶名称或执行6表联接。额外的存储是浪费(但真的,谁在乎呢?),但现在也打开了不一致的可能性。俗话说得好:“有表的人知道现在几点;一个有两个孩子的人永远不会真正确定。它使更新复杂化。如果你想更新一批酶的名称,而不是仅仅更新,比如
PRODUCED.CONSTRUCT_ID
,现在您还需要记住更新CHAR_ENZ
也。反规范化不一定是魔鬼,但你应该用它来避免更糟糕的问题。一个6表连接可能不是一个“更糟糕”的问题,不足以证明它是正确的(显然在我看来,没有多少细节)。
实际上,就我个人而言,我可能只会使用6表连接。你可以考虑把
PRODUCED
,PURIFIED_ENZ
,和CHAR_ENZ
在物理数据库设计期间,集群中的表。这应该将性能影响降到最低。您还可以创建一个视图来封装连接逻辑。如果要反规范化,可以选择“一路”不反规范化。也就是说,例如,您可以使用复合键来进行某种非规范化,但仍然可以从数据完整性约束中获益。例如。,
PURIFIED_ENZ
==>主键(G_BATCH, P_BATCH)
CHAR_ENZ
==>主键(G_BATCH, P_BATCH, CHAR_ID)
这也违反了第三范式,如果你想报警的话。但这使得一个CHAR_ENZ
行和“非规范化”G_BATCH
列。你可以用G_BATCH
为了减少连接的大小,需要获得酶的名称。关于您的数据模型,我关心的最后一件事是,它似乎假设并要求生产的步骤1-3总是相同的。技术变革;客户要求变更。我对微生物学知之甚少,但一般来说,我想用较少的假设建立一个数据模型。您可以通过稍微抽象一下批处理步骤来实现这一点。