我正在尝试理解数据库规范化,特别是3NF。
我正在建立一个商店数据库,并试图规范化为3NF已经提出了下面的结构。
以下结构假设
任何人都可以告诉我,如果我在正确的轨道上,是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
我不确定的两件主要事情:
使用Product_categories的复合键来容纳表中多个相同的PID是否正确?
简单地将一个外键添加到manufacturer和storage_location的主要Products表是否正确,因为每个产品记录只会出现一次?或者应该从主产品表中删除特定的制造商和storage_location id,并创建新表:
Product_storage_locations
----------------------------------
PID (pk)
storage_location_id (pk)
答案 0 :(得分:1)
通过使用三个表 - 产品,类别,product_category - 您将在产品和类别之间建立多对多关系。即任何一个产品都可以属于多个类别,任何一个类别都可以分配给多个产品。如果这不是意图,那么这不是正确的设计。
相反,如果你有一对多的关系,那么你只需要两个表。在此设置中,“many”表条目将外键保存到“one”表中。看起来您的设计是正确的,只要一对多就是您对产品 - 制造商关系的要求。如果你想要多对多,你需要一个三表设计。
BTW,product_category表中的两个字段都是外键(fk),而不是您指定的主键。
答案 1 :(得分:1)
是的,你看起来对我来说是正确的。您将产品存储位置和制造商放在Products
表中所做的绝对正确。如果你把它放在一个单独的表格中(在底部),你将只为自己创造更多的工作,以及你以后需要做的所有连接。
您将其拆分为新的Product_storage_locations表的唯一原因是,产品可能位于多个位置(根据您所说的情况,并非如此)。但是,对于产品和类别,是您想要做的事情 - 这就是您使用Product_categories表所做的事情;并且绝对是正确的事情。
我在你的设计中唯一不确定的是你如何做额外的领域。如果没有关于您的意图的更多信息,很难说您所做的事情是否正确。不过,在我看来,你所拥有的是一种特殊类型的领域,可能适用于许多产品;但是,这些产品中的每一个可能对该领域具有不同的价值。如果这是你的意图,那么这个设计看起来很好。