fomvasss
@fomvasss
PHP developer

Структура базы данных магазина/каталога для SQL. Как лучше хранить атрибуты и их значения в БД?

Планируется разработка "стандартного" интернет-магазина (реализация будет на Laravel).
Должно быть:
  • категории товаров (categories: электроника, огород, книги,...)
  • товары (products), при этом товары разных категорий имеют разные атрибуты
  • атрибуты (attributes: цвет, масса, размер)
  • значения атрибутов (values: зеленый, красный, 1, 2, 5, m, s, xl, xxl)


При создании товара, указываем категорию, потом, в зависимости от выбранной категории, можно указать значения атрибутов (атрибуты и их значения должны быть созданы заранее).

Нарисовал следующую структуру БД:
5c0914558df34478073273.png

Пока что, теоретически, как бы все должно работать. Но хотелось ли увидеть комментарии/советы, у кого был опыт подобной работы. Возможна ли такая реализация на практике и не столкнусь ли я, с пока что не известными мне, проблемами и ограничениями?
  • Вопрос задан
  • 43655 просмотров
Решения вопроса 2
@stratosmi
Неверно в корне.
Вы нарисовали по сути EAV (есть такая готовая схема данных под эту задачу - погуглите, примеров много).

Плюсы:
Удобно ложиться в реляционную модель, удобно программируется (если вам удобно работать с реляционной моделью), на первый взгляд хорошо подходит под любую реляционную СУБД (MySQL, PostgreSQL, Oracle).

Минусы:
Неоправдано малоэффективно по производительности.
Есть решения на порядок более быстрые.

Впрочем, если у вас каких то жестких требований на производительность или на минимизацию затрат на сервер - годится.

По мне так EAV удобен как средство редактирования (ну и хранения первичной информации).

А вот собственно сам поиск гораздо эффективнее осуществляется на full-text search engines, например:
SphinxSearch (или его клон Мантикора), ElasticSearch и т.п.

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

В наиболее развитых full-text search engine поиск по свойствам является "дешевой" операцией, совершенно совместимой с основным полнотекстовый поиском.

Более того, работа с множественными фильтрами по свойствам в этих движках даже проще полнотекстового поиска (так как фильтры не нужно разбивать на слова, прогонять через алгоритм стемминга с его возможными косяками - они уже "готовы к употреблению" сразу).

Бонусом практически "бесплатно" получаете т.н. "фасеточные итоги", отвечающие на вопрос "сколько у нас товаров с таким то свойством" (это часто используется в отображении фильтров на сайтах).

====================

Вывод:

Если вам принципиально на MySQL - просто см. описание схемы данных EAV. Она как раз именно что для этого.
Если вам нужно чтобы все летало - см. SphinxSearch (он крайне быстр и нетребователен к ресурсам).

P.S.:
SphinxSearch
Умеет выдирать данные из MySQL. На их основании строит уже свой собственный узкоспециализированный но очень быстрый поиск для выборок, в вашем случае, по названию и по свойствам товаров.
Ответ написан
@dimoff66
Кратко о себе: Я есть
1) Не очень понятно назначение таблицы product_value, допустим у вас есть товар Куртка зимняя, у него есть два варианта (цвет: черный, размер: 42), (цвет: красный, размер: 43), и что будет в таблице?
Четыре записи:
Куртка зимняяЦвет черный
Куртка зимняяЦвет красный
Куртка зимняяразмер 42
Куртка зимняяразмер 43


И как вы определите, как эти свойства соотносятся и главное как вы это будете использовать?
У вас же будут вноситься данные по продажам?

Назначение этой таблицы в таком виде непонятно, я бы предложил сделать таблицы

attributes_sets (модификации товара)
  • id
  • product_id
  • title


и

attributes_sets_values (значения свойств данной модификации)
  • attributes_set_id
  • value_id


Тогда получится таблица вида

Куртка: вариант 1 Цвет черный
Куртка: вариант 1размер 42
Куртка: вариант 2 Цвет красный
Куртка: вариант 2размер 43


и в таблицах с движениями товаров можно указывать просто id модификации, которая и будет содержать полную информацию о включенных в него значениях атрибутов.

Также можно писать в поле title таблицы attributes_sets значения модификации через запятую "черный, 42", это упростит вывод информации о модификации в отчетах.

2) В product_value(или attributes_sets_values, если примените пункт 1) можно добавить поля attribute_id, value_int, это позволит для числовых атрибутов не задавать заранее список значений в values, а сразу указывать числовое значение

3) Цены лучше не хранить в товаре, а сделать отдельные таблицы

price_types: id, name
prices: price_type_id, product_id, set_date, price

Это позволит назначать товару разные цены в зависимости от всякого рода условий, можно также добавить в prices поле user_id, чтобы не возникал вопрос кто поменял цену
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Я в подобной ситуации, использовал поле с типом JSON. Т.е. содержимое такого поля у одного товара может быть таким: [ "color" : black, "size" : 42, "gender" : "male", "season" : "winter"], а у другого следующим : [ "color" : black, "size" : 42, "kind" : "mountain", "sole" : "vibram"]. Нынешний MySQL позволяет по таким полям осуществлять поиск, а в ЯП имеются функции по раскодировке JSON в обычный массив.
Ответ написан
alex-1917
@alex-1917
Если ответ помог, отметь решением
Вот тебе подсказка (см. скрин), правда, убраны цвета, с ними на порядок больше возни и в БД и при поиске.
Т.е. разный цвет - это разный товар.
spoiler
5c0944920a573194551741.jpeg


С другой стороны, иногда и цвета надо включать в комбинацию, т.е. один товар - это комбинация размера и цвета. Это актуально, если поставщик (или основная масса твоих поставщиков) отгружаюттебе что-тотипа такого ассортимента - если присмотреться, там на одном артикуле висят и размеры и цвета. дебильно конечно, но иногда без вариков
spoiler
5c094598084fa584329730.png
Ответ написан
Ваш ответ на вопрос

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

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