【问题标题】:Database Normalization chaining数据库规范化链接
【发布时间】:2015-10-30 07:13:08
【问题描述】:

我有多个表链接,如下所示:

表1

product_id SERIAL NOT NULL,
name varchar,

Table2 (与table1分开,因为产品名称相同但颜色可以不同)

table2_id
product_id integer,
color varchar,
FOREIGN KEY (product_id) REFERENCES table1 (product_id) ON DELETE CASCADE

table3 (与table2分开,因为产品颜色相同,但尺寸可以不同)

table3_id
table2_id integer,
size varchar,
FOREIGN KEY (table2_id) REFERENCES table2 (table2_id) ON DELETE CASCADE

例如,产品数据可能以这样的方式存在:

a chair (name)  -  red (color)  - 100cm(size)
a chair (name)  -  red (color)  - 200cm(size)
b chair (name)  -  green (color)  - 100cm(size)
b chair (name)  -  green (color)  - 200cm(size)
c chair (name)  -  black (color)  - s(size)
c chair (name)  -  black (color)  - m(size)
d chair (name)  -  black (color)  - null(size)
e chair (name)  -  gold (color)  - big(size)
e chair (name)  -  gold (color)  - small(size)

为了规范化表格(即删除重复项),我将它们分成 3 个表格,但我不确定这样的链接是否正确。

【问题讨论】:

  • 你正在做的是不是规范化。规范化不会引入新列(例如 ids)。您也没有提供规范化所需的信息(FD 和 JD)。如果 product_ids 是 1:1 且名称在 table1 中,则示例数据表已经 在 5NF 中。所以你有一些误解。我已经解释了这个here(刚刚编辑)。
  • 1.您的“因为”不清楚,并且您没有解释每个“因为”与相应表的存在之间的联系。 2. 说出 a) 您的“产品数据”“表”中的一行在 product_id、名称、颜色和大小方面的表述以及 b) 列的值必须始终与一组不包含它的列的相同子行值。

标签: database database-design relational-database


【解决方案1】:

是的,这很好,但可以说模型应该是这样的:

product -< product_variant >- product_size

                  V
                  |
           product_colour

【讨论】:

  • 感谢回复,你的意思是我的数据和你的例子一样吗?我不确定我明白你的意思吗?我认为它更像product -&gt; product_color -&gt; product_size ----&gt; product_priceproduct -&gt; product_color -&gt; product_size ----&gt; product_qty 似乎我必须从product -&gt; product_color -&gt; product_size 链接
  • 产品变型表可以是产品、产品尺寸和产品颜色表的子表,并包含价格。
  • `@DavidAldridge (&@user1775888):我不认为 user1775888 正在构思产品变体,我认为他认为每次给定的子元组出现多次时他都必须有一个 id .即我认为他实际关心的数据是示例数据并且它已经在 5nf 中。
【解决方案2】:

您似乎认为每次给定的子元组在表中出现多次时都需要一个 id。即您正在尝试删除不需要删除的“重复项”。多次出现的相同值不是标准化意义上的“重复”,也不一定是坏的。此外,您对多个表和 id 的使用都不是规范化。 (我已经尝试解决这个表定义“链接”反模式here。)

来自this answer

问题是一辆公共汽车在同一站停了好几次 不同的时间,我怎么能存储这些信息避免 冗余?

不存在这样的问题。无论是否存在“冗余”,一个子行都可以在表中出现多次。 (无论您认为这意味着什么。虽然可以用 id 和另一个表替换多次出现的 subrows,但是对于相同的查询结果,需要更多的 joins。参见 @987654323 @.)

或来自that answer's link

这与规范化无关。规范化永远不会创建新的列名。 “我不希望“任天堂”被复制”是误解。值出现在多个地方本身并没有错。请参阅 sqlvogel 和我自己 here 的答案。

“冗余”与出现在多个位置的值无关。它是关于多行说明应用程序的相同内容。当使用这样的设计时,有两个基本问题:说某些事情涉及多行(而规范化版本只涉及一行);并且没有办法一次只说一件事(规范化可以提供帮助)。如果您对 Nintendo 做出两个不同的独立陈述,那么您需要两张表,并且每张表中都提到了 Nintendo。重新对应用程序进行陈述的行参见this。 (并在我的其他答案中搜索表的“声明”或标准“。)规范化有帮助,因为它用声明“...”的其他表替换了行状态为“... AND ...”形式的事物的表分别。参见thisthis。(标准化通常被错误地认为涉及或包括避免多个相似的列,避免值具有重复结构的列和/或用 id 替换字符串,但尽管这些可能是很好的设计理念,但它们'不是标准化。)

来自my answer at that answer's first link

如果 SUBJECT_MODULE 是“[SUBJECT_NAME] 具有 [MODULE_NAME] 由 [MODULE_ID] 标识”的行,并且一个主题可能有多个模块,那么您必须在某处多次提及该主题(也许通过它的名字)提到不同的模块(也许是名字或id)。这不会涉及冗余。

【讨论】:

    【解决方案3】:

    这是您提交的same question 的第二个版本。答案是一样的。

    产品是一个实体。大小和颜色是属性。

    表包含实体。每个实体由一行表示。每行的字段是每个实体的属性。您不必每次需要向实体添加属性时都创建新表。这将使关系数据库无法使用。

    【讨论】:

    • 实体不由行表示,它们由值表示。属性是二元关系,由值对表示,而不是由单个列表示。表/行表示实体之间的一种或多种关系。见陈的论文The Entity-Relationship Model - Toward a Unified View of Data
    • 我承认不熟悉陈,您也没有提供这样做的链接。我只能参考整个关系数据库著作——几乎是 Date 等。您对行、实体和关系的描述仅在行确实代表关系的交叉表的非常狭窄的上下文中才有意义。但是,交集表不是这里的主题。
    • 好的,我找到了参考。事实证明,您所描述的是来自关系集的元组(第 12 页)。这与本次谈话的主题相去甚远。
    • 参见第 6 页和第 8 页关于表示实体的第 2.3.1 节,以及第 4 页关于属性的第 2.2.3 节。看来您的解释与日期相匹配(至少在An Introduction to Database Systems 第 8 版第 14 章中)。我支持 Chen 的解释,它将实体/集合映射到值/域,而不是像 Date 建议的那样映射到元组/相关变量。我相信 Date 关于第一个大错误的论点也适用于实体集,因为将它们映射到 relvar 与 relvar 不是域的格言相矛盾,而实体集显然是属性和关系的域。
    • 如果您继续到 2.3.2,您将看到实体 EMPLOYEE 从概念形式到逻辑形式的良好转换。图 7 准确地显示了我一直在说的内容。 Chen自己的描述:“图7中的整个表是一个实体关系,每一行都是一个实体元组。”下一阶段将是物理表。不同之处仅在于逻辑属性“名称”将是两个字段 First-Name 和 Last-Name。无论如何,虽然这对我来说很有趣,而且我认为你也很有趣,但它仍然与 OP 最初的问题无关。还是我错过了什么?
    猜你喜欢
    • 2011-11-12
    • 2012-10-08
    • 2012-06-21
    相关资源
    最近更新 更多