2016-05-10 3 views
-1
line_item (id, description, parent_id, product_id); 
product (id, model); 

Пример иерархии ПОЗИЦИИЕсли бы я не хотел использовать NULL, как бы я нормализовал эту таблицу?

Product A  //"parent" "line item" 
    Option 1 //child "line item"s of "parent" 
    Option 2  

Текущий DB Data

line_item: 
id | description | parent_id | product_id 
----------------------------------------- 
1 | Product A |  NULL |   20 //has no parent "line item" 
2 | Option 1 |   1 |   -1 //no product associated with option 
3 | Option 2 |   1 |   -1 //has "line item" parent with id == 1 
product 
id | model 
-------------- 
20 | Product A 

Вопрос

Я не совсем уверен, как избавиться от «NULL» от parent_id. Обратите внимание, что я использую -1 в моем product_id, а также, где я использую его подобным образом, говоря «нет„продукта“или„родителя“, связанного с этой конкретной записью позиции.

ли мне нужно к избавиться от него в первую очередь?

+0

Есть ли у каждого продукта варианты? Могут ли опции иметь вспомогательные параметры? –

+0

На практике каждая «позиция» может иметь свои собственные опции, потому что на самом деле ... мы используем «родительские позиции», которые не всегда являются продуктами. Чаще всего они есть, но не всегда. Параметры не имеют дополнительных опций. – Dennis

+1

Тогда я не вижу необходимости в таблице иерархии. Одна таблица для «родительских позиций», одна для «опционных позиций». –

ответ

1

Прежде всего, вы должны заменить -1 нулевым. Это вполне законная ценность.

Нулевые значения фактически не играют роли при рассмотрении нормализации, поскольку вы можете говорить только о функциональной зависимости, если у вас есть ненулевые значения, поэтому вам не нужно беспокоиться о нормализации, ваша таблица в порядке ,

Ваша таблица представляет собой реализацию «disjunct is-a», что означает, что line_item является либо «опцией» -лайн (со значением parent_id), либо «товарной» линией (с значение product_id и, например, quantity, ...) и имеет общие значения id и description. Disjunct означает, что он не может быть одновременно одновременно, поэтому столбцы для другого типа имеют значение null (поэтому вам нужно «заменить -1 нулевым»).

Обычная реализация «disjunct is-a» заключается в добавлении type -колона, который определяет, какая из этих возможностей (причина более практична, например, для проверок ограничений). Здесь вам это не нужно, так как вам ясно, что это за линия без этой области, но я добавил ее, чтобы подчеркнуть, что вы на самом деле осуществляете, и что вы делали все стандартным образом:

line_item: 
id | description | line_type | parent_id | product_id 
----------------------------------------------------- 
1 | Product A | Product |  NULL |   20 
2 | Option 1 | Option |   1 |  NULL 
3 | Option 2 | Option |   1 |  NULL 

Последнее замечание: Существуют и другие возможные реализации «is-a», некоторые из них избавляются от нулевого (при введении других проблем), но для вариантов дизъюнкции это обычный. Но так как это ответит на ваш первоначальный вопрос («Если бы я не хотел использовать null ...«), Я добавлю этот тоже:

line_item: 
id | description 
----------------- 
1 | Product A 
2 | Option 1 
3 | Option 2 


line_item_product: 
line_item_id | product_id 
--------------------------- 
      1 |   20 

line_item_option: 
line_item_id | parent_id 
--------------------------- 
      2 |   1 
      3 |   1 

У вас есть таблица для общих столбцов (для обоих типов option и product) и отдельный стол для двух возможностей с их конкретными столбцами

.

Это избавиться от нулевой

Самая большая практическая проблема состоит в том, что вы должны иметь более сложную проверку на «первичный ключ» в двух таблицах line_item_option и line_item_product:. вы не можете добавлять строка 1 в line_item_option, когда она уже находится в line_item_product, но mysql не может легко проверить это. Вот почему этот вид расщепления используется только тогда, когда у вас есть «недискриминация есть-a» -реляция (например, если строки могут быть одновременно и продуктом, и опцией).

+0

Спасибо !. Теперь ваш представитель 666, и у вас есть 6 бронзовых значков. Это похоже на чтение советов от дьявола! – Dennis

+0

Теперь, когда вы отошли от зла, я могу принять и выпустить, не нарушая ваши злые пути. Ха-ха, я, конечно, шучу, надеюсь, вы знаете, что – Dennis

1

NULL правильный путь не представлять никакой ценности.

Кроме того, для надлежащей практики, если добавить внешний ключ на поле parent_id, который ссылается на родительский Line_Item, или product_id, вы не могли использовать -1.

+0

спасибо. Я не совсем понял, что «не мог использовать -1». parent_id - это внешний ключ, указывающий, какая строка в той же таблице считается «родителем» определенной позиции. Когда родитель отсутствует, он устанавливается в '-1' или может быть установлен вместо« NULL ». – Dennis

+0

Вы можете установить [FOREIGN KEY CONSTRAINT] (http://dev.mysql.com/doc/refman/5.7/en/create-table-foreign-keys.html), чтобы убедиться, что все данные в таблице являются когерентными , Вы не можете установить -1 в поле, если у вас нет строки с идентификатором -1 (ошибка mysql throw). NULL является более надежным и уважительным. – ebahi

1

Я думаю, вы хотели бы сохранить NULL без изменений, потому что он может использоваться как индикатор того, какие записи являются элементами верхнего уровня. Кроме того, таблицы уже выглядят нормализованными, поэтому нормализация не имеет отношения к вашей проблеме.

Смежные вопросы