【问题标题】:Trying to understand database normalization - 3NF试图理解数据库规范化 - 3NF
【发布时间】:2012-01-04 11:27:39
【问题描述】:

我正在尝试了解数据库规范化,尤其是 3NF。

我正在建立一个商店数据库,并在尝试规范化为 3NF 时提出了以下结构。

下面的结构假设

  • 每个产品可能有多个类别
  • 每个产品只有一个 storage_location 和制造商
  • 可能有无限的额外字段

谁能告诉我我是否走在正确的轨道上,下面的结构是 3NF 中的,还是关闭的?

Products
----------------
pid (pk)
title
desc
price
weight_base
weight_additional
note
quantity
manufacturer_id (fk)
storage_location_id (fk)

Categories
-----------------
category_id (pk)
category_name
parent_id
description

Product_categories
-----------------
pid (pk)
category_id (pk)

Manufacturers
-------------------
manufacturer_id (pk)
name
description

Storage_locations
---------------------

storage_location_id (pk)
storage_ref
storage_note

Product_extra_field_values
-----------------------------------

PID (pk)
extra_id (fk)
value

Product_extra_fields
--------------------------------

extra_id (pk)
label

我不确定的两件事主要是:

  1. 对 Product_categories 使用复合键来容纳表中的多个相同 PID 是否正确?

  2. 只需将外键添加到制造商和 storage_location 的主 Products 表中是否正确,因为它们在每个产品记录中只会出现一次?或者是否应该从主 Products 表中删除特定的制造商和 storage_location id,并像这样创建新表:

    Product_storage_locations
    ----------------------------------
    PID (pk)
    storage_location_id (pk) 
    

【问题讨论】:

    标签: mysql normalization database-normalization 3nf


    【解决方案1】:

    通过使用三个表——product、category、product_category——您可以在产品和类别之间建立多对多关系。 IE。任何一种产品都可以属于多个类别,并且任何一种类别都可以分配给多个产品。如果这不是意图,那么这不是正确的设计。

    相反,如果你有一个一对多的关系,那么你只需要两个表。在此设置中,“许多”表条目将外键保存到“一”表中。只要一对多是您想要的产品-制造商关系,看起来您的设计是正确的。如果要多对多,则需要三表设计。

    顺便说一句,product_category 表中的两个字段都是外键 (fk),而不是您指出的主键。

    【讨论】:

    • 您在底部的注释并不完全正确-它们是其他表的外键,是的;但它们也自己构成主键。每个表都需要一个主键;在这种情况下,因为多个类别可以应用于单个产品;并且多个产品可以应用于单个类别,它们都不是唯一的,因此您确实需要将两者一起作为主键。
    • 我的看法不同,但我明白你的意思
    【解决方案2】:

    是的,在我看来,你所拥有的一切都是正确的。您将产品存储位置和制造商放在Products 表中所做的事情是绝对正确的。如果你把它放在一个单独的表中(在底部),你只会为自己创造更多的工作,你以后必须做的所有连接。

    您将其拆分为新的 Product_storage_locations 表的唯一原因是产品是否可能位于多个位置(根据您所说,情况并非如此)。但是,对于产品和类别,您想要做的 - 这就是您对 Product_categories 表所做的;并且绝对是正确的做法。

    我在您的设计中唯一不确定的是您是如何完成额外字段的。如果没有更多关于你的意图的信息,很难说你所做的是否正确。不过,在我看来,您所拥有的是一种可能适用于许多产品的特定类型的字段;但是这些产品中的每一个都可能对该字段具有不同的价值。如果这是您的意图,那么该设计看起来不错。

    【讨论】:

    • 感谢您的回答 - 我正在考虑使用 extra_field 动态添加额外的可选产品数据,例如条件(新的或使用的)。但是考虑一下 Product_extra_field_values 在上述示例的情况下将充满相同的值,即“新”或“使用”,因此创建第三个额外字段表可能会更好,例如“Product_extra_field_value_options”,该表将具有 value_option_id 和 value_option_value然后在 Product_extra_field_values 表中有 value_option_id 而不是“value”
    猜你喜欢
    • 2010-12-15
    • 1970-01-01
    • 1970-01-01
    • 2016-08-17
    • 2014-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多