Моделирование продуктов с совершенно разными наборами необходимой информации и привязка их к элементам линейки? - PullRequest
4 голосов
/ 29 июля 2010

В настоящее время я работаю над сайтом, на котором продаются товары разных типов, изготовленные на заказ. У меня есть ваша общая стандартная схема корзины: у Order есть много LineItems, у LineItems есть один Product, но я столкнулся с небольшим камнем преткновения:

Допустим, один из наших продуктов - это шарик, а один из наших продуктов - коробка с карандашами. Пока люди создают свои заказы, мы в конечном итоге создаем элементы, которые могут быть представлены некоторым псевдокодом:

Ball:
  attributes:
     diameter: decimal
     color: foreign_ref_to Colors.id
     material: foreign_ref to Materials.id
CrayonBox:
  attributes:
     width: decimal
     height: decimal
     front_text: string
     crayons: many_to_many with Crayon
...

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

Я подумал о нескольких возможных решениях, но ни одно из них не кажется идеальным:

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

LineItem
  information: many_to_many with product_information
  ...
ProductInformation:
  lineitem: many_to_many with line_item
  name: string
  value: string

ProductInformation(name='color', value=$SOMECOLOR)
ProductInformation(name='color', value=$SOMEOTHERCOLOR)
...

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

Другое решение, о котором я подумал, заключается в том, чтобы у таблицы LineItem был внешний ключ для каждой таблицы, представляющей тип Product. К сожалению, это означает, что мне придется проверять наличие каждого внешнего ключа в моем контроллере. Мне это совсем не очень нравится, но мне это нравится немного лучше, чем объединять все данные в один тип данных, а затем разбираться со всеми вещами преобразования вне БД.

Еще одним возможным решением было бы сохранение имени таблицы данных о продукте в столбце, но это не может быть хорошей вещью, не так ли? Я теряю способность БД связывать вещи вместе, и мне кажется, что использование eval() там, где оно не нужно, - все мы знаем, что eval() на самом деле не нужно очень часто.

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

Итак, люди, которые действительно знают, что они делают со схемой базы данных, что мне делать? Как я должен представлять это? Похоже, что это будет довольно распространенный вариант использования, но я не смог найти много информации с поиском в Google - есть ли общий шаблон для подобных вещей? Нужна дополнительная информация? Это не может быть за пределами "вы можете использовать СУБД для этого", не так ли?

Редактировать: Теперь я совершенно уверен, что мне нужно здесь Наследование таблиц классов . с псевдонимом в моих индивидуальных моделях для «нормализации» ссылки, следующей за таблицей «информация» для каждого типа продукта. К сожалению, ORM, который я как бы застрял для этого (Doctrine 1.2), не поддерживает наследование таблиц классов. Возможно, мне удастся добиться чего-то похожего с наследованием «агрегации столбцов» Доктрины, но, например. Кто-нибудь думает, что я лаю не на том дереве? Я просмотрел EAV и не думаю, что это вполне соответствует проблеме - каждый набор информации о разных продуктах известен, хотя они могут сильно отличаться от типа продукта A к типу B. Гибкость EAV может быть хорошей , но похоже на злоупотребление БД для такой проблемы.

Ответы [ 3 ]

1 голос
/ 11 августа 2010

Мне кажется, что это идеально подходит для CouchDB / MongoDB , которые позволяют каждой «строке» содержать различные атрибуты, но разрешают индексированный поиск. Было бы довольно просто построить гибридную структуру, используя MySQL для жестких реляционных частей и 'nosql' для частей различной формы.

0 голосов
/ 29 июля 2010

Допущения:

У вас есть конкретные продукты, которые вы продаете.То есть ты знаешь, что продаешь мелки, а не шпатели.Клиент не заходит на ваш сайт и не пытается заказать продукт, о котором вы никогда не слышали.

Продукты, которые вы продаете, имеют уже существующий набор атрибутов.Т.е. мелки имеют цвет;crayon_boxes имеют ширину, высоту, мелки ... Клиент не заходит на ваш сайт и не пытается указать значение атрибута, о котором вы никогда не слышали.

Один из способов сделать это (если вы 'если вы пурист RBDM, пожалуйста, закройте глаза, пока я не скажу вам открыть их снова), это использовать строку атрибутов.Таким образом, таблица будет выглядеть так:

Products

+ ProductName
+ ProductAttribute

И тогда пример записи будет выглядеть следующим образом:

  • Product Name = "Crayon Box"
  • ProductAttribute = "Высота: 5 дюймов; Ширина: 7 дюймов"

С чем-то вроде этого, анализируйте пары имя / значение по мере необходимости.

0 голосов
/ 29 июля 2010

Взгляните на это обсуждение .

...