Многоуровневые предметы - PullRequest
3 голосов
/ 21 декабря 2011

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

В настоящее время у меня есть следующие таблицы:

Item:

  • Item_ID (PK)
  • Имя

Main_Option:

  • Main_Option_ID (PK)
  • Имя

Sub_Option:

  • Sub_Option_ID (PK)
  • Main_Option_ID (FK)
  • Имя

Item_To_Sub_Option

  • Item_ID
  • Sub_Option_ID

Это структура, которая у нас есть в настоящее время - вот пример, чтобы продемонстрировать, как она работает:

Элемент: Диван

Main_Option: Длина

Sub_Option: 40 ”-50”

Item_To_Sub_Option: Item_ID дивана, 40 ”-50” Sub_Option_ID

Вы получаете изображение.До здесь это довольно прямо вперед.По сути, он позволяет каждому элементу иметь неограниченное количество подопций и основных опций.

Теперь мы стремимся достичь детального описания описанного решения или многоуровневого опционного решения.

Например, более сложный элемент, в котором мне нужно создать дополнительные параметры, но эти параметры создаются не из элемента, а из других дополнительных параметров.Пример следующим образом:

Элемент: Диван

Main_Option: Shape

Sub_Option: 1/2 Circle

"1/2 circle" должен иметьДОПОЛНИТЕЛЬНО Main_Option - «Диаметр», который будет иметь Sub_Options (раунд 50 ”, раунд 60” и т. Д.).Эти параметры не связаны напрямую с элементом, но с подопцией «1/2 круга», которая была выбрана ранее на верхнем уровне.

Каков наилучший способ разработки базы данных для достижения этого решения?

Ответы [ 2 ]

2 голосов
/ 23 декабря 2011

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

Если вы думаете оосновные параметры как «особенности» или «качества» и подопции как «значения», тогда это становится немного понятнееВ вашем примере диван имеет качество «ФОРМА».Для ваших целей форма может быть линейной или круглой.Линейные формы имеют качество ДЛИНА, в то время как круглые имеют качество УГОЛ.Ни одно из этих качеств не имеет значений : ФОРМА, ЛИНЕЙНАЯ, КРУГЛЫЙ.Однако эти качества: ДЛИНА, УГОЛ действительно имеют значения.Значения для LENGTH могут быть такими, как 40 "-50" , а для ANGLE может быть 1/2 Circle .

Поэтому ваша модель данных не нуждается вочень сильно измениться:

ERD

Просто добавьте еще один FK из MAIN_OPTION к себе.Вы заметите, что это было также предложено Дэвидом, за исключением того, что Дэвид предложил это как плохой второй вариант, тогда как в действительности это хороший первый выбор.

Ваши правила иерархичны, и СУБД может быть неудобным для иерархических данных, если вы не углубляетесь в иерархию .Когда вы углубляетесь, тогда каждый шаг прост.

0 голосов
/ 22 декабря 2011

Есть два способа придумать что-то подобное.Однако первое, что нужно признать, это то, что ваши данные по своей структуре иерархичны и не обязательно очень регулярны.Это означает, что использование традиционной реляционной базы данных не будет особенно подходящим для данных этого типа.Тем не менее, это может быть сделано.

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


Item {
   main_options: [{
      name: "Shape",
      sub_options: [{
          name: "1/2 Circle",
          //  Other fields here
      }]
   },
   {
      //  Other main option
   }]
}

Прелесть этого типа модели данных на основе документов заключается в том, что существует нет фиксированной схемы, которой вы должны придерживаться.Если элементу требуется несколько вложенных наборов параметров, вы просто идете вперед и определяете документ этого элемента таким образом.Несмотря на то, что каждый «элемент» документа потенциально сильно отличается, все они хранятся в одной «коллекции», и вы можете выполнять запросы для поиска различных элементов.Таким образом, вы можете попросить базу данных найти все элементы с подопцией «1/2 Circle», например, «Shape».

Если вы привыкли работать с реляционными базами данных, переходя к чему-то вроде MongoDBэто что-то вроде изменения сознания, но я думаю, что в этом случае это вполне соответствовало бы природе ваших данных.

С другой стороны, если вам абсолютно необходимо использовать реляционную базу данных, вынужно моделировать вещи как иерархию, которая может быть немного сложнее.В основном вам нужны таблицы, немного похожие на те, что вы уже описали, хотя я переформулировал их с изменениями, которые я сделал бы здесь:


item (id (pk), name: text, ...)

option (id (pk), owner: option_id (fk), name: text, ...)

item_options (item_id, option_id)

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

В таблице опций есть дополнительное поле «owner», которое для основных опций вы бы установили в «null», но для вложенныхпараметры, вы должны установить в этом поле идентификатор опции основной опции или, возможно, подопцию, которая «владеет» ею.Используя такую ​​структуру, вы можете вкладывать свои параметры на любую глубину.Вот некоторые примеры данных:


item (1, "Sofa", ...)
option (1, null, "Shape", ...)
option (2, null, "Length", ...)
option (3, 1, "1/2 Circle", ...)
option (4, 1, "3/4 Circle", ...)
option (5, 2, "Short", ...)
option (6, 2, "Long", ...)
option (7, 5, "Specific Short Measurement", ...)
option (8, 5, "Other Short Measurement", ...)
item_options (1, 1)
item_options (1, 2)

Недостатком использования реляционной базы данных для этого типа данных является то, что запросы для поиска вещей не очень просты.Например, чтобы найти все диваны с параметром «1/2 круга», вам может понадобиться что-то вроде:


select * from item i inner join item_options io on i.id = io.item_id inner join option o on io.option_id = o.id left join option o2 on o.id = o2.owner where o.name = 'Shape' and o2.name = '1/2 Circle'; 

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

В любом случае, я надеюсь, что это даст вам несколько вариантов того, как моделировать вещи.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...