Database design 在执行数据库规范化时,将重复的行信息集合并到新的实体中是什么?

Database design 在执行数据库规范化时,将重复的行信息集合并到新的实体中是什么?,database-design,database-normalization,Database Design,Database Normalization,我对数据库规范化的某一部分有点困惑,我想问StackOverflow: 假设您有以下关系,将产品与颜色联系起来。请注意,产品1和产品2都使用相同的颜色集(蓝色和绿色) 如果我创建两个新关系,ColorSet和ColorSet_Color,我可以通过将这4个关系连接在一起来显示相同的信息 Product_ColorSet: ColorSet_Color: +-------------+-------------+ +--------

我对数据库规范化的某一部分有点困惑,我想问StackOverflow:

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

如果我创建两个新关系,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       |
+-------------+                   +----------[--+-------------+
在这一点上,如果我有一个大的Product_颜色表,有一个合理程度的共享颜色组,从空间角度来看,我将获得相当大的收益

在数据库规范化上下文中,此操作的技术名称是什么?很明显,我正在删除冗余信息,尽管我创建的实体实际上并不存在,但这更像是随机发生的,有很多重叠。通过这样做,我具体改变了什么

此外,我似乎可以任意地对大多数实体执行此操作。让我困惑的是,当我们开始练习时,产品的颜色和颜色已经是第六种标准形式了(对吧?)。

您正在引入一个“(或标识符)来命名/识别产品的颜色集。备选方案通常被认为是一个“或标识符”。(尽管不同的人在细节上使用这些术语的方式不同。例如,有些人可能只使用“代理”当一个名称/标识符被永久地分配给一个引用对象和/或是其引用对象的唯一名称/标识符和/或它仅在数据库中可见,而不是在应用程序中可见时。例如,有人会说,一个外部可见的系统生成的任意名称/标识符(如驾驶员识别号)既是一个代理项,也是一个自然项。)

代理键通常称为“无意义(标识符)”。这反映出思维混乱。所有不是由先验命名方案生成的名称都是“无意义”的&任意的。“尼古拉斯”不是“指”你,直到它被选中;被选中后,它“意味着”你。这适用于任何名称/标识符。因此,“无意义”/“有意义”并不是一个有用的区别。系统中的代理名称/标识符只是在系统启动后选择的名称/标识符。在一个系统中被称为“有意义的”[sic]的东西,如果被分配到之前存在的任何系统中(因为分配是在它开始之后),就会被称为“无意义的”[sic]

在“透视图”中,您可以“删除冗余信息”,但这不是规范化所解决的冗余类型。您正在用其他表替换一个表,但这不是规范化分解。引入代理不是规范化的一部分。规范化不会引入新的列名。它只是在替换它的表中重用原始表的名称。(你能清楚准确地描述你这里所说的“多余”是什么意思吗?)

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

这不是您应该费心通过表设计来解决的冗余。如果您知道DBMS对表的实现选项,并且知道应用程序的使用模式,并且您知道原始选项明显比某些碰巧“较少冗余”的选项更糟糕(为什么“较多冗余”选项不更好?)然后,如果可以的话,在不更改模式的情况下,您应该告诉DBMS您想要的设计选项。(这通常是通过索引和/或视图完成的。)例如,在ColorId上为原始产品_颜色编制索引会导致实现中的结构与您在第二次设计中手动创建的结构基本相同,但会自动生成和管理。(您可能出于其他原因引入代理,例如用更简洁但值更模糊和受约束的外键替换多列外键。)

重新选择:新设计将在查询文本和(对于典型的DBMS实现)执行中使用比原始(例如查询原始表)更多的操作(例如连接和投影),但在其他地方使用更少的操作(例如将一个产品的颜色集复制到另一个颜色集)。因此,这也是关于多种“视角”的权衡

事实上,在另一种意义上,您引入了代理冗余。还有一些额外的列包含一组id值,这些id值不是原始的,但它们记录了相同的情况。您还为用户带来了更多命名和间接的设计负担。与原始设计相比,代理设计在这个“透视图”中当然有很多“冗余信息”

甚至您的初始设计也可能引入了代理,即颜色名称的颜色ID。(如果颜色ID添加了“信息”,即“通知”您的不仅仅是它们的相关名称,那么它们将不是代理,并且是必要的。)例如,如果颜色ID是任意选择的,则您可以:

Product_Color
+-------------+-------------+
| Product*    | ColorName*  |
+-------------+-------------+
| 1           | Blue        |
| 1           | Green       |
| 2           | Blue        |
| 2           | Green       |
+-------------+-------------+
您应该有理由引入颜色ID,以及产品ID,而不是现有的自然关键点。你能证明你的多个表、名称和间接性而不是一个吗?

你正在引入一个“”(或标识符)来命名/识别产品的颜色集。备选方案通常被认为是一个“或标识符”。(尽管不同的人在细节上使用这些术语的方式不同。例如,有些人可能只在姓名/i
Product_Color
+-------------+-------------+
| Product*    | ColorName*  |
+-------------+-------------+
| 1           | Blue        |
| 1           | Green       |
| 2           | Blue        |
| 2           | Green       |
+-------------+-------------+