taral
@taral
php программист

Различные варианты товара в интернет магазине. Преимущества и недостатки реализаций

Здравствуйте. Я приведу какие способы реализаций придумал/подсмотрел я. Возможно есть гораздо лучшие решения.
Различные варианты товаров в интернет магазине могут выводится такими способами
rozetka.com.ua/acer_liquid_mt_s120_silver/p144068/ — странички практически отличаются. У каждого своя цена, свои изображения (название, могут быть и свои акции и т.д.)
shop.dinternal.com.ua/textbook/excellent/ — товара как такового нет. Он просто комплект других товаров (хотя своя цена тоже может быть. К примеру за все товары вместе.) Еще особенность это разделение вариантов по группам. В более простом варианте очень часто используется в каталогах машинных деталей.

Других вариантов отображения товаров я не встречал.
Теперь поговорим про решения.
1. Товары полностью отличаются и связываются много к многому через смежную таблицу
Преимущества
— можно реализовать что угодно
Недостатки
— дублируется очень много информации
— сложно реализовать информацию которая относится ко всем товарам (общие комментарии, оценка товара пользователями и т.д.)
— если описание товара изменилось нужно менять его во всех его вариациях.
2. Некое наследование. Есть главный товар. Другие товары наследуемые.
По умолчанию у них не заполнено ни одно поле кроме id товара от которого происходит наследование. Когда мы выводим товар и у него есть поле id родителя + выводимое поле пустое берется значение главного товара.
Преимущества
— комментарии, оценку пользователей можно ставить на товар родитель.
— заполняется информация различная для товаров. Одновременно с этим мы не теряем в гибкости
Недостатки
— У товара может быть 30 разных полей. Выходит у товара-вариации они все будут пустыми. База данных будет магко говоря корявой
— В ORM получение полей родителя не должно отличатся от обычного получения полей товара (для прозрачной работы). С другой стороны при редактировании объект должен вести себя совершенно по другому выдавая настоящие значения полей.
— В базе данных некоторые поля могут быть обязательными для заполнения. Хотя по текущей логике работы системы они должны быть пустыми.
3. Вынести цену товара отдельно от товара и добавить к ней поле название вариации. Этот способ встречался мной чаще всего. И он в большинстве случаев лучший.
Преимущества
— Не хранится лишней информации. И база данных заполняется без пробелов.
— Реализует большинство задач
Недостатки
— Требует значительной модификации кода если вдруг потребуется сделать вывод как в розетке. И вообще для такого способа группировки товаров он слабо подходит
— Значительно усложняется работа с ценами товара.
— Практически исключается поиск конкретной модификации товара и также вывод нескольких модификаций в каталоге как разных товаров.
Буду рад любым замечаниям и советам. Цель создать такую структуру базы данных что бы с минимальными телодвижениями можно было реализовать максимальное количество способов отображения товаров.
  • Вопрос задан
  • 9344 просмотра
Пригласить эксперта
Ответы на вопрос 6
@Pyatochkin
поскольку пишу 2-й раз — буду краток ;) не буду пугать количеством реализованных «складов», сразу приведу пример довольно универсального справочника товаров (естественно, в упрощенном виде ;)
Таблица 1 — goods:
id, Name
Таблица 2 — params:
id, Name(например — Производитель, Длина, )
Таблица 3 — goods_params:
id, goods_id(foreign key), param_id(foreign key), Value

в такой схеме товар имеет имя(в некоторых случаях его можно генерить автоматом по заполненным данным из goods_params — будет как общее описание товара в розетке), а все его характеристики в goods_params, пустых полей нет, добавление товара с новыми характеристиками добавит записей в goods, params, goods_params. В ширину таблицы расти не будут. Надеюсь, схема понятна? Ключи/индексы не расписаны… Дальше это можно наворачивать еще долго… проблем с подбором, поиском и сопоставлением товара здесь нет — решается банально через SQL(что-то вроде расширенной версии такого подхода отлично работает в оракловой базе под 1,5TB). ну а насколько данная фантазия ляжет на ваш orm — это другой вопрос — вы не это спрашивали ;)
ну где хранить цену — вопрос обычно отдельный ;) хотя, в некоторых случаях войдет в уже описанную схему… в общем, дерзайте ;)
Ответ написан
@Pyatochkin
не выдержал, пришел еще раз… ;) я читаю что мне пишут а вы не читаете даже себя ;) если написано «Для обычного поиска по названию товара придется делать массу телодвижений» а подразумевается что-то другое то тут только телепаты помогут угадать ;) а я своих телепатов по мелочам не беспокою ;) так что ответил на то, что написано а не подразумевалось ;)
вы опять демонстрируете не понимание работы с бд на достаточно свободном уровне ;) это, как говорится без обид, но факт ;) дабы продемонстрировать часть ваших заблуждений, обращу внимание на такой факт что понравившееся вам слово EAV, принципиально не мешает вам работать в дальнейшем с данными так, как будто они хранятся в flat table ;) т.е. можно получить выборку вида:
goods_id, goods_name, param1, param2, pram3,…
где будут те самые пустые поля если данного атрибута нет у товара. к такому набору данных вы сможете применять банальный select ;) гибкое хранение на то и гибкое, дабы не ограничивать в дальнейшей работе (привет от К.О. ;). ответ на вопрос как сделать такую работу более комфортной, несколько зависит от применяемой СУБД и задач, но обычно подойдет view(а вы их вообще пробовали использовать?)…
ну, еще можно сделать умное лицо и спросить про перфоманс такой схемы ;) зная предпологаемый размер таблиц, тип субд, используемое железо, а в некоторых случаях и количество пользователей — обычно легко ответить — справитесь? :)
Ответ написан
Комментировать
@Chii
Что мешает реализовать сразу все три варианта и для каждой группы товаров использовать наиболее подходящий?
Ответ написан
@Pyatochkin
к сожалению, правильный ответ — читать о проектировании БД вообще и нормализации в частности… один из критериев «правильной структуры» БД — это то, что ваши таблицы не растут в ширину при добавлении новых свойств для ваших объектов (в вашем случае — это св-ва товаров). Соответственно одним из критериев «плохой структуры» будет множество пустых в большинстве записей полей, сделанных «про запас». Ну а то, что хранение данных в БД, связи между таблицами и т.д. НИКАК не должны ограничивать отображение — это легко понять, взглянув на описание паттерна MVC. В общем обычно, оправдан такой подход — нормализуем БД до предела, продумав рост (по возможности, конечно ;). Тогда при достаточном знании SQL нет проблем что-то найти ;) Если у вас реляционная БД и вы хотите работать только через ORM, нигде не кастомизируя запросы, то вы не всё сможете реализовать…

P.S. все ваши 3 варианта, как бы это сказать, не по фэншую ;)
Ответ написан
@Pyatochkin
пипец писал полчаса и все пропало :( ох уж эти веб редакторы… еще вернусь…
Ответ написан
Комментировать
taral
@taral Автор вопроса
php программист
Такое хранение характеристик широко известно под названием Entity Attribute Value. Я применяю этот подход, но для «не стандартных» полей. Хотя несколько модифицированный и заточенный именно под магазин. Но вынос всех характеристик по такому принципу еще большее зло чем сотни пустых товаров. Для обычного поиска по названию товара придется делать массу телодвижений (а для поиска по названию и фильтрации по цене, вообще без HAVING или вложенного запроса не обойтись). Тем более что дизайн добавления и редактирования товара тоже должен быть не набором полей для заполнения. А для этого мы должны пойти по одному из трех путей: забить и вывести просто списком, добавить для каждой характеристики поле отвечающее за вид инпута (но что делать если расположение этих инпутов тоже не должно быть стандартным), сделать эти поля статичными (оставить то что есть сейчас). Я считаю что если сломя голову гнаться за гибкостью системы (а EAV несомненно самый гибкий вариант) можно достичь такой сложности редактирования всего этого, что мы опять же придем к обычному созданию таблиц, только в своей реализации.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы