Прежде всего, вы должны заменить -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» -реляция (например, если строки могут быть одновременно и продуктом, и опцией).
Есть ли у каждого продукта варианты? Могут ли опции иметь вспомогательные параметры? –
На практике каждая «позиция» может иметь свои собственные опции, потому что на самом деле ... мы используем «родительские позиции», которые не всегда являются продуктами. Чаще всего они есть, но не всегда. Параметры не имеют дополнительных опций. – Dennis
Тогда я не вижу необходимости в таблице иерархии. Одна таблица для «родительских позиций», одна для «опционных позиций». –