3

我试图了解数据库规范化,特别是 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 表中删除特定的制造商和 storage_location id,并像这样创建新表:

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

2 回答 2

1

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

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

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

于 2011-11-23T05:28:42.390 回答
1

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

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

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

于 2011-11-23T05:37:01.887 回答