Магазин. Как лучше описать аттрибуты и свойства продукта?

hammet

Новичок
Магазин. Как лучше описать аттрибуты и свойства продукта?

Представим бд интернет магазина, допустим торгующего моб. телефонами.
Итак телефон - это продукт. У него есть группа аттрибутов, например "камера" или "интерфейсы",
каждая группа содержит ряд аттрибутов продукта (пары имя - значение), как пример для камеры это
размер матрицы = 1234х5678 пкс
кратность зума = 4х
тип вспышки = LED
и так далее.
К тому же, группы и аттрибуты могут повторяться для большинства товаров (т.е. многие телефоны оснащены камерами, у которых есть определенные свойства), но будут отличаться значениями (5Mpx, 1.3Mpx, 2Mpx).

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

Моя идея такова, таблицы:
product (id, ...)
product_attribute (product_id, attribute_id)
attribute (id, property_id, value)
property (id, group_id, name)

таким образом в таблице property сохраняю имена групп и самих свойств (group_id можно читать как parent_id), в таблице attribute я связываю группу, свойство и даю ему значение, ну и связываю это всё с таблицей продуктов. Таким образом можно избежать избыточности данных, но приходится тащить в запросах по 4-5 таблиц минимум...

Использоваться это всё будет при детальном поиске по товарам (т.е. можно задать точные критерии выборки) и при выводе информации о товаре (т.е. сама страница товара). Всё.

Может стоит упростить схему? Вобщем покритикуйте, пока я не зарылся.
 

Fortop

Новичок
EAV

Но лучше гибридное решение.

5-10 полей в обычной таблице с товарами просто под именами ATT1,...,ATT10
и описания(названия) отдельно.
 

dimagolov

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

hammet

Новичок
Fortop, спасибо за ответ, читаю про EAV.
Гибридное решение мне не подходит, т.к. при большом количестве товаров детальный поиск будет производиться по таблице товаров, а не по аттрибутам, что значительно быстрее. Да и всё не вместишь в 10 полей, не гибкая схема, в любом случае

-~{}~ 26.02.10 17:43:

dimagolov
спасибо. уже искал.
Тема, в принципе не особо сложная, тут главное вовремя остановиться и определить для себя наименее трудоёмкую и ресурсоёмкую схему в рамках текущего проекта.

Можно, конечно, и так:
product(id, ...)
product_attribute(id, product_id, name, value)

и всё.

будет много повторений - да, будет мульён записей при 10к товара - снова да. Зато запросы и апи простые.

вобщем..."думай, Трофимов" (с)
 

Fortop

Новичок
Да и всё не вместишь в 10 полей, не гибкая схема, в любом случае
Поместить можно все, если иметь голову на плечах. Схема потому и гибридная, что несущественные атрибуты хранятся в EAV таблицах, но поиск и агрегация по ним не реализовываются.

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

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

P.S. И да, фантазии о большом количестве товаров и атрибутов - лучше оставить в фантазиях.
 

hammet

Новичок
Fortop
Я для себя вынес пользу из статьи про EAV http://en.wikipedia.org/wiki/Entity-attribute-value_model - это как раз то, к чему я шёл. За это спасибо. Замечание сделал по поводу манеры общения... Мой совет - будь проще ;)
 

Fortop

Новичок
Мой совет - будь проще
Не давайте советов пока к Вам за ними не обратятся.

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

http://209.85.135.132/search?q=cache:3GSGrmwdb4QJ:fenix.kiev.ua/archives/33-EAV_vs_Row_Modeling._Test_proizvoditelnosti_na_PostgreSQL.html+EAV+недостатки&cd=1&hl=uk&ct=clnk&gl=ua
 

zerkms

TDD infected
Команда форума
С EAV, вместе с "гибкостью" (кавычки значимые), ты получишь тонну головняков на выборках.

почему бы просто не вынести в одну таблу общие свойства (вроде PK, title, price, added, picture, итд) и в отдельные таблицы - частные свойства.

сходи и внимательно посмотри серьёзные магазины вроде amazon, ozon, ebay, market.yandex...
 

brook

Новичок
hammet

Почему не сделать стандартный вариант который уже предложили?

products (...fields...)
product_options (...fields....)
product_option_values (...fields....)

По сути это твой же вариант - product(id, ...)
product_attribute(id, product_id, name, value) только нормализированный, name вынесен. API очень простое, поиск будет простым.
 

newARTix

Новичок
brook
простым? Сложность запроса, во всех смыслах, растет геометрически с ростом кол-ва полей участвующих в поиске. А если нужен поиск не тупо по равенству, а исключающий, по диапазону, с группировкой по "ИЛИ" то это просто превращается в ад. В чем гибкость EAV для меня так и остается загадкой... Неужели проще откровенно извращаться с каждой реализацией поиска для каждого нового интернет-магазина (в котором заказчик обычно снова хочет какого-нибудь только ему понятного алгоритма выборки), чем просто один раз написать класс который будет просто вносить необходимые изменения в структуру БД с изменением классификатора каталога... то есть реализовывать простейшую и понятную Row модель. Вопросы возникают только в моменты изменения моделей сущностей, но... В общем непонятно мне пока. Так же как преимущества Nested Sets при количестве нод менее 1000 (а необходимость работы с деревом с большим количеством нод уже вопрос к проектировщикам).
 

brook

Новичок
newARTix

Мало того что простым - да еще и очевидным. Критерии для поиска можно рендерить автоматически на основе типа поля и т.д. Писали, искали. проверяли ;)
 

SiZE

Новичок
Я бы сделал справочник сущностей в виде дерева.

Родитель мобильник, у него дочерний раздел камера, в камере дочерние разделы разрешение зум и тд.

table guide

g_id - int
g_name - varchar
g_level - tinyint
g_position - varchar - Записывать строки вида 00001.
g_parent - int
 
Сверху