试图了解数据库规范化 - 3NF

时间:2011-11-23 05:19:42

标签: mysql normalization database-normalization 3nf

我正在尝试理解数据库规范化,特别是3NF。

我正在建立一个商店数据库,并试图规范化为3NF已经提出了下面的结构。

以下结构假设

  • 每个产品可能有多个类别
  • 只有一个storage_location&每个产品的制造商
  • 可能有无限的extra_fields

任何人都可以告诉我,如果我在正确的轨道上,是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. 简单地将一个外键添加到manufacturer和storage_location的主要Products表是否正确,因为每个产品记录只会出现一次?或者应该从主产品表中删除特定的制造商和storage_location id,并创建新表:

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

2 个答案:

答案 0 :(得分:1)

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

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

BTW,product_category表中的两个字段都是外键(fk),而不是您指定的主键。

答案 1 :(得分:1)

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

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

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