Попытка понять нормализацию базы данных - 3NF

Я пытаюсь понять нормализацию базы данных, в частности 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

Я не уверен в двух основных вещах:

  1. Правильно ли использовать составной ключ для Product_categories для размещения нескольких идентичных PID в таблице?

  2. Правильно ли просто добавить внешний ключ в основную таблицу продуктов для производителя и storage_location, потому что они будут появляться только один раз для каждой записи продукта? Или следует удалить конкретный производитель и идентификатор storage_location из основной таблицы Products и создать новые таблицы следующим образом:

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

person someuser    schedule 23.11.2011    source источник


Ответы (2)


Да, то, что у вас есть, мне кажется правильным. То, что вы сделали, указав место хранения продукта и производителя в Products таблице, абсолютно правильно. Если вы поместите его в отдельную таблицу (внизу), вы просто создадите для себя больше работы со всеми соединениями, которые вам нужно будет сделать позже.

Единственная причина, по которой вы должны разделить это в новую таблицу Product_storage_locations, - это то, что продукт может находиться в нескольких местах (что, согласно тому, что вы сказали, не так). Однако в случае продуктов и категорий это , что вы хотите сделать - и это то, что вы сделали с таблицей Product_categories; и это абсолютно правильно.

Единственное, в чем я не уверен в вашем дизайне, так это в том, как вы сделали дополнительные поля. Без дополнительной информации о ваших намерениях трудно сказать, правильно ли вы поступили. Однако мне кажется, что у вас есть поля определенного типа, которые могут применяться ко многим продуктам; но при этом каждый из этих продуктов может иметь различное значение для этого поля. Если это ваше намерение, то этот дизайн выглядит нормально.

person Smashery    schedule 23.11.2011
comment
Спасибо за ответ - я думал об использовании extra_field для динамического добавления дополнительных дополнительных данных о продукте, таких как состояние (новое или использованное). Однако если подумать об этом, Product_extra_field_values ​​будет содержать идентичные значения в случае приведенного выше примера, то есть «новый» или «использованный», поэтому, возможно, было бы лучше создать третью таблицу extra_field, например, «Product_extra_field_value_options», которая будет иметь value_option_id и value_option_value а затем вместо value в таблице Product_extra_field_values ​​укажите value_option_id - person someuser; 23.11.2011

Используя три таблицы - product, category, product_category - вы устанавливаете отношение «многие ко многим» между продуктами и категориями. Т.е. любой продукт может принадлежать нескольким категориям, и любая категория может быть назначена нескольким продуктам. Если это не намерение, значит, это неправильный дизайн.

И наоборот, если у вас есть отношение «один ко многим», вам понадобятся только две таблицы. В этой настройке «многие» записи таблицы удерживают внешний ключ в «одной» таблице. Похоже, ваш дизайн правильный, если вы хотите, чтобы отношения продукт-производитель соответствовали принципу «один ко многим». Если вы хотите «многие ко многим», вам понадобится дизайн с тремя таблицами.

Кстати, оба поля в таблице product_category являются внешними ключами (fk), а не первичными ключами, как вы указали.

person Dmitry B.    schedule 23.11.2011
comment
Ваше примечание внизу не совсем верно - это внешние ключи в других таблицах, да; но они также сами составляют первичный ключ. Каждой таблице нужен первичный ключ; и в этом случае, поскольку несколько категорий могут применяться к отдельным товарам; и несколько продуктов могут применяться к отдельным категориям, ни одна из них не является уникальной сама по себе, поэтому вам действительно необходимо иметь оба вместе в качестве первичного ключа. - person Smashery; 23.11.2011
comment
Я смотрел на это по-другому, но я понимаю, что ты имеешь в виду - person Dmitry B.; 23.11.2011