在进行数据库规范化时,将重复的行信息集组合成新的实体是什么?

Nic*_*son 0 database-design database-normalization

我对某些数据库规范化有些困惑,并认为我会问StackOverflow:

想象一下,您具有以下将产品与颜色相关联的关系。请注意,产品1和产品2都使用相同的颜色集(蓝色和绿色)。

Product_Color                         Color
+-------------+-------------+     +-------------+-------------+
| Product*    | Color*      |     | ColorId*    | Name        |
+-------------+-------------+     +-------------+-------------+
| 1           | 1           |     | 1           | Blue        |
| 1           | 2           |     | 2           | Green       |
| 2           | 1           |     +-------------+-------------+
| 2           | 2           |
+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

如果创建两个新的关系ColorSet和ColorSet_Color,则可以通过将这4个关系连接在一起来显示相同​​的信息。

Product_ColorSet:                 ColorSet_Color:             
+-------------+-------------+     +-------------+-------------+
| Product*    | ColorSetId* |     | ColorSetId* | ColorId*    |
+---------------------------+     +-------------+-------------+
| 1           | 1           |     | 1           | 1           |
| 2           | 1           |     | 1           | 2           |
+-------------+-------------+     +---------- --+-------------+

ColorSet:                         Color:
+-------------+                   +-------------+-------------+
| ColorSetId* |                   | ColorId*    | Name        |
+-------------+                   +-------------+-------------+
| 1           |                   | 1           | Blue        |
| 2           |                   | 2           | Green       |
+-------------+                   +----------[--+-------------+
Run Code Online (Sandbox Code Playgroud)

在这一点上,如果我有一个大的Product_Color表,并且具有合理程度的共享颜色组,那么从空间角度来看,我将获得很多好处。

在数据库规范化背景下,此操作的技术名称是什么?即使我创建的实体实际上不存在,我也显然正在删除多余的信息,而这是很多重叠的随机机会。通过执行此操作,我具体要更改什么?

此外,似乎我可以随意对大多数实体执行此操作。让我感到困惑的是,当我们开始练习时,Product_Color和Color已经是第6个正常形式(对吗?)。

phi*_*pxy 5

您正在引入“ 代理键 ”(或标识符)来命名 / 标识产品所使用的颜色集。通常将替代方法视为“ 自然键 ”(或标识符)。(尽管不同的人使用这些术语的方式有所不同。例如,某些人可能仅在名称/标识符被永久分配了一个参照对象和/或是其参照对象的唯一名称/标识符和/或仅与数据库一起可见时才使用“代理”。而不是应用程序。例如,有些人会说,由外部可见的系统生成的任意名称/标识符(例如驾驶员识别号)既是替代品也是自然的。)

代理键通常称为“无意义(标识符)”。这反映出思维混乱。不是由先验命名方案生成的所有名称都是“无意义的”和任意的。在被选中之前,“尼古拉斯”并不“意味着” 。被选中后,它“意味着”您。这适用于任何名称/标识符。因此,“无意义” /“有意义”不是有用的区分。系统中的代理名称/标识符只是系统启动后选择的名称/标识符。什么被调用系统中的“有意义的” [原文]会被称为“毫无意义” [原文]在任何系统之前就已经存在(因为任务是分配之后,当开始)。

在“透视图”中,您正在“删除冗余信息”,但这不是规范化解决的那种冗余。您正在用其他表替换表,但这不是规范分解。引入代理人不是标准化的一部分。规范化不会引入新的列名。它只是在替换原始表的表中重用原始表的名称。(您是否能够清楚准确地描述“冗余”在这里的意思?)

有时人们认为,如果相同的值子集可以在列集或表中出现多次,则这些子行值需要用FK的ID替换为将ID值映射到子行值的新表的ID。(甚至对于单列子行来说,也就是当一个值在一个列或表中出现多次时)。他们认为多个子行值的出现是“冗余的”,或者只有id可以重复而不是“冗余的”。(id设计被视为原始数据的一种压缩。)他们可能认为这是规范化的一部分。这些都不是。

这不是冗余,您不应该通过表设计来解决。如果您知道DBMS的表的实现选项,并且知道应用程序的使用模式,并且知道原始版本在某种程度上比碰巧“较少冗余”的选项明显更有意义(并且为什么不这样做, “更多冗余”选项会更好吗?)然后您应该告诉DBMS设计所需的选项,如果可以的话,不要更改架构。(这通常是通过索引和/或视图完成的。)例如,在ColorId上索引原始Product_Color会导致实现中的结构与您在第二个设计中手动创建的结构基本相同,但会自动生成和管理。(您可能会出于其他原因而引入代理人,例如用更简洁的值替换多列的外键,尽管它们的价值和含义更加晦涩难懂。)

重新选项:您的新设计将在查询文本和(对于典型的DBMS实施)执行的查询文本中使用更多的操作(例如,联接和投影)(对于典型的DBMS实现)将比原始操作(例如,查询原始表)执行更多操作,但在其他地方(例如,复制一种产品的颜色集)则使用更少的操作给别人的)。所以,这又是所有关于权衡多个 “角度”。

实际上,从另一种意义上讲,您已经在代理中引入了冗余。还有其他一些列,它们包含一堆id值,这些值不在原始记录中,但记录了相同的情况。您还给用户增加了更多命名和间接设计的负担。与原始设计相比,代理设计在此“视角”中肯定具有许多“冗余信息”。

甚至您的初始设计都可能引入了代理,即颜色名称的颜色ID。(如果颜色标识添加了“信息”,即“告知”您的信息不仅仅是它们的关联名称,那么它们将不是替代品,而是必要的。)即,如果任意选择颜色标识,则您可以拥有:

Product_Color
+-------------+-------------+
| Product*    | ColorName*  |
+-------------+-------------+
| 1           | Blue        |
| 1           | Green       |
| 2           | Blue        |
| 2           | Green       |
+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

您应该有理由引入颜色ID,并为此引入产品ID,而不是已有的自然键。您能否证明您的多个表,名称和间接引用与一个表的合理性