В настоящее время я работаю над сайтом, на котором продаются товары разных типов, изготовленные на заказ. У меня есть ваша общая стандартная схема корзины: у 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 может быть хорошей , но похоже на злоупотребление БД для такой проблемы.