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

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

Других вариантов отображения товаров я не встречал.
Теперь поговорим про решения.
1. Товары полностью отличаются и связываются много к многому через смежную таблицу
Преимущества
— можно реализовать что угодно
Недостатки
— дублируется очень много информации
— сложно реализовать информацию которая относится ко всем товарам (общие комментарии, оценка товара пользователями и т.д.)
— если описание товара изменилось нужно менять его во всех его вариациях.
2. Некое наследование. Есть главный товар. Другие товары наследуемые.
По умолчанию у них не заполнено ни одно поле кроме id товара от которого происходит наследование. Когда мы выводим товар и у него есть поле id родителя + выводимое поле пустое берется значение главного товара.
Преимущества
— комментарии, оценку пользователей можно ставить на товар родитель.
— заполняется информация различная для товаров. Одновременно с этим мы не теряем в гибкости
Недостатки
— У товара может быть 30 разных полей. Выходит у товара-вариации они все будут пустыми. База данных будет магко говоря корявой
— В ORM получение полей родителя не должно отличатся от обычного получения полей товара (для прозрачной работы). С другой стороны при редактировании объект должен вести себя совершенно по другому выдавая настоящие значения полей.
— В базе данных некоторые поля могут быть обязательными для заполнения. Хотя по текущей логике работы системы они должны быть пустыми.
3. Вынести цену товара отдельно от товара и добавить к ней поле название вариации. Этот способ встречался мной чаще всего. И он в большинстве случаев лучший.
Преимущества
— Не хранится лишней информации. И база данных заполняется без пробелов.
— Реализует большинство задач
Недостатки
— Требует значительной модификации кода если вдруг потребуется сделать вывод как в розетке. И вообще для такого способа группировки товаров он слабо подходит
— Значительно усложняется работа с ценами товара.
— Практически исключается поиск конкретной модификации товара и также вывод нескольких модификаций в каталоге как разных товаров.
Буду рад любым замечаниям и советам. Цель создать такую структуру базы данных что бы с минимальными телодвижениями можно было реализовать максимальное количество способов отображения товаров.
10 февраля в 18:49
2
taral 3,3
случайно подумал — а ТС умеет юзать поиск? видимо нет — ибо уже было Pyatochkin,
Тему про EAV начали вы. Я же говорю что для текущего примера это бред. Потому смысл кидать мне ссылку где обсуждается именно этот подход и указывать что я не умею использовать поиск… taral,

отсортировано по дате по оценке
ответы (6)

0
Chii #
Что мешает реализовать сразу все три варианта и для каждой группы товаров использовать наиболее подходящий?
ну 3 варианта в любом случае реализовывать не стоит. Ведь 1 и 2 по сути очень похожи. А объединить оба варианта в принципе можно taral, 12 февраля в 03:40
0
Pyatochkin #
к сожалению, правильный ответ — читать о проектировании БД вообще и нормализации в частности… один из критериев «правильной структуры» БД — это то, что ваши таблицы не растут в ширину при добавлении новых свойств для ваших объектов (в вашем случае — это св-ва товаров). Соответственно одним из критериев «плохой структуры» будет множество пустых в большинстве записей полей, сделанных «про запас». Ну а то, что хранение данных в БД, связи между таблицами и т.д. НИКАК не должны ограничивать отображение — это легко понять, взглянув на описание паттерна MVC. В общем обычно, оправдан такой подход — нормализуем БД до предела, продумав рост (по возможности, конечно ;). Тогда при достаточном знании SQL нет проблем что-то найти ;) Если у вас реляционная БД и вы хотите работать только через ORM, нигде не кастомизируя запросы, то вы не всё сможете реализовать…

P.S. все ваши 3 варианта, как бы это сказать, не по фэншую ;)
На счет первых двух совершенно согласен. Мне тоже не нравятся эти решения. Хотя они дают чрезвычайную гибкость реализации поставленных задач. К тому же отчасти решение пустых полей можно решить таким образом. Разделить таблицу товаров на 2 части. В одной будут 100% уникальные поля. В другой те что будут дублироваться. Третий же вариант мне кажется наилучшим если не учитывать что он хорошо подходит для более узкого круга задач.
Вы говорили про то что записи в базе данных никак не должны ограничивать отображение. Совершенно согласен. Но такого результата в большинстве случаев можно достичь в лабораторных условиях а не в реальных проектах.
Я предпочитаю работать через ORM. Хотя при надобности чистый sql это не проблема.
taral, 12 февраля в 04:43
все таки повторюсь ;) читайте про нормализацию, потому как ваши рассуждения полях и таблицах, кхм, несколько наивны ;) и да — отделить данные от бизнес логики и отображения — достижимая без всякой магии реальность ;) опыт, вдумчивое чтение манов и попытки следовать «хорошему стилю» дают результаты :) с другой стороны, если что-то работает с «не идеальной» архитектурой и уже решает ваши задачи — то лучше так, чем ненаписанная «идеальная» система ;) в общем, удачи :) Pyatochkin, 13 февраля в 14:14
У меня складывается впечатление, что вы по большей степени теоритик. И не реализовывали задачи на практике. Конечно я могу ошибаться. И если вас это оскорбило, приношу свои извинения. Первые 2 решения это единственный гибкий вариант который я смог придумать для решения поставленных задач (и я был бы искренне рад, если бы вы предоставили более хорошее решение. Ведь для имитации таблиц нужно всего 4 поля: id, цена, название, описание. Где id, название, цена уникальны для каждого товара, а описание общее для всех. Также нужно учесть что общих и уникальных полей может быть значительно больше). Из всех форумов и обсуждений на которые я его выносил улучшение предложили в разделении таблицы товаров на 2 по тому принципу что я описал ранее. Третий же способ разделения цен применяется в львиной доле CMS интернет магазинов. И никакой избыточности в себе не несет. Про разделение данных и бизнес логики я вообще не говорил. Тем более модель в любом случае затачивается под таблицу с которой она работает. Указывая на недостатки текущей модели без предоставления альтернатив несколько не по фэншую =) taral, 13 февраля в 21:55
0
Pyatochkin #
пипец писал полчаса и все пропало :( ох уж эти веб редакторы… еще вернусь…
0
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 — это другой вопрос — вы не это спрашивали ;)
ну где хранить цену — вопрос обычно отдельный ;) хотя, в некоторых случаях войдет в уже описанную схему… в общем, дерзайте ;)
ну и еще в догонку… если говорить о пректировании БД «по взрослому», стоит, хотя бы минимально освоить нечто вроде Sybase PowerDesigner(я его выбрал для себя из 5-6 опробованных вариантов). как и любая хрень для UML-моделирования, позволяет оценить некоторые решения ДО реализации(да и сэмплы там приличные есть — будет что посмотреть). и если UML для собственно программ, в продакшене себя оправдал только для обсуждений(его оказалось нереально суппортить синхронно с кодом), то для БД мне иногда удавалось рефакторинг, или даже почти всю разработку, делать через PowerDesigner :) ну а reverse engineering существующих баз позволяет наглядно увидеть с каким безобразием предстоит работать ;) Pyatochkin, 16 февраля в 01:38
0
taral #
Такое хранение характеристик широко известно под названием Entity Attribute Value. Я применяю этот подход, но для «не стандартных» полей. Хотя несколько модифицированный и заточенный именно под магазин. Но вынос всех характеристик по такому принципу еще большее зло чем сотни пустых товаров. Для обычного поиска по названию товара придется делать массу телодвижений (а для поиска по названию и фильтрации по цене, вообще без HAVING или вложенного запроса не обойтись). Тем более что дизайн добавления и редактирования товара тоже должен быть не набором полей для заполнения. А для этого мы должны пойти по одному из трех путей: забить и вывести просто списком, добавить для каждой характеристики поле отвечающее за вид инпута (но что делать если расположение этих инпутов тоже не должно быть стандартным), сделать эти поля статичными (оставить то что есть сейчас). Я считаю что если сломя голову гнаться за гибкостью системы (а EAV несомненно самый гибкий вариант) можно достичь такой сложности редактирования всего этого, что мы опять же придем к обычному созданию таблиц, только в своей реализации.
последний ответ можно трактовать так — автор не осилил работу со стандартной струтурой ;) если у вас есть проблемы с тем, как корректно заполненные данные отображать — это или не правильный инструмент или недостаток навыков ;) более того вы опять пришли к пункту что храненение данных вам диктует отображение и редактирование ;) перестаньте это смешивать в 1 кучу, используйте mvc паттерн или что-то подобное и будет вам щастье. если нет возможности или желания сделать все красиво — вас здесь никто не заставляет, но не надо свои ограничения (вероятнее всего придуманные) излагать как общую проблему ;) у вас стандартная задача(хранение) и никакой нестандартный интерфейс(даже если он и в правду нестандартный ;) не отменит того, что хранить данные можно гибко.
ваши рассуждения про sql заставляют подумать что вы боитесь его использовать ;) не бойтесь — это не больно ;) при работе с базой его все равно придется юзать и если заспрос сложнее обычного селекта вызывает приступ паники, то проблема все равно не имеет отношения к архитектуре. более того «Для обычного поиска по названию товара» HAVING не нужен… в sql еще много интересных слов ;) а поскольку имя товара предложено хранить в читаемом виде в таблице goods — даже боюсь представить, откуда проблемы с поиском ;)

в общем, на вопрос вам ответили, а нежеление/неумение использовать нормальные варианты не надо оправдывать надуманными проблемами ;) если лень — то хотя бы себе надо признатся — да — лень ;) остальные и так догадаются ;)

P.S. я всё здеся, больше не приду
Pyatochkin, 16 февраля в 16:10
Вы читали мое сообщение? Я написал что EAV применяется. Но в данном конкретном примере его использование мягко говоря сумасшествие. У меня все больше и больше складывается впечатление что вы знаете все это только по наслышке, и не работали в реальных условиях. То что предложили вы — хорошо может выглядеть только на бумаге. Высказывание про HAVING остается в силе. Вообще забавно. Вы так силитесь меня учить, а как вижу с EAV сами не работали. Без HAVING или вложенного запроса вы не сделаете поиск по нескольким атрибутам одного товара (зачем было говорить про расположение названия товара в goods. Понятное дело что имелось в виду про тот атрибут который находится в смежной значений) Если простые слова вас все не убеждают могу привести пример такого SQL запроса. narod.ru/disk/40930454001/%D0%B7%D0%B0%D0%BF%D1%80%D0%BE%D1%81.xls.html. Повторюсь еще раз. Представление не диктует мне структуру хранения данных в базе. Но я смотрю весь процесс целиком, а не на малую его часть. При хранении этих полей через EAV вы сделаете такую грыжу для реализации остального функционала что и свет белый не милым будет. И лень тут ни при чем. Тут только здравый смысл. Да и база тут не выиграет. В лучшем случае для выбора 5 товаров с характеристиками у вас будут 5 дополнительных запросов. А для обычных случаев будет по 100 и больше. Но вы все эти моменты не учли. Зачем спрашивается. Нам же нужно взять все значения характеристик. Конечно это можно решить кешированием, но зачем ломать себе руку что бы ее потом лечить. Я сказал все что хотел. taral, 16 февраля в 19:04
А забыл еще можно сделать запрос через туеву кучу join'ов. По одному на каждую характеристику taral, 16 февраля в 20:29
0
Pyatochkin #
не выдержал, пришел еще раз… ;) я читаю что мне пишут а вы не читаете даже себя ;) если написано «Для обычного поиска по названию товара придется делать массу телодвижений» а подразумевается что-то другое то тут только телепаты помогут угадать ;) а я своих телепатов по мелочам не беспокою ;) так что ответил на то, что написано а не подразумевалось ;)
вы опять демонстрируете не понимание работы с бд на достаточно свободном уровне ;) это, как говорится без обид, но факт ;) дабы продемонстрировать часть ваших заблуждений, обращу внимание на такой факт что понравившееся вам слово EAV, принципиально не мешает вам работать в дальнейшем с данными так, как будто они хранятся в flat table ;) т.е. можно получить выборку вида:
goods_id, goods_name, param1, param2, pram3,…
где будут те самые пустые поля если данного атрибута нет у товара. к такому набору данных вы сможете применять банальный select ;) гибкое хранение на то и гибкое, дабы не ограничивать в дальнейшей работе (привет от К.О. ;). ответ на вопрос как сделать такую работу более комфортной, несколько зависит от применяемой СУБД и задач, но обычно подойдет view(а вы их вообще пробовали использовать?)…
ну, еще можно сделать умное лицо и спросить про перфоманс такой схемы ;) зная предпологаемый размер таблиц, тип субд, используемое железо, а в некоторых случаях и количество пользователей — обычно легко ответить — справитесь? :)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.