Как спроектировать базу для интернет-магазина?

Что-то сложнее блога с комментариями и категориями никогда не проектировал. Обучения ради интересуют вопросы проектирования.

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

Самый примитив как я понял это создание под каждую категорию своей таблицы, где столбцы это атрибуты.
Но тогда, товар не может присутствовать в нескольких категориях, а если пересекаются бренды, то чтобы сделать выборку по бренду всех товаров, нужно лезть во все таблицы и фильтровать по бренду? В общем здесь пока больше вопросов.

Другой нагуглил вариант, EAV - Entity Atribute Value. Вроде всё логично и правильно, категория может являться атрибутом, название категории значением, тоже самое с брендами, бренд атрибут, название это значение. По этой модели работает Magento CMS, количество таблиц там намного больше конечно. Также гуглится что это анти-паттерн и очень плохо и медленно.

Подскажите какие есть варианты проектирование е-коммерса, в гугле и в гите встречаю либо очень сложные для понимания варианты либо примитив где товар нельзя добавлять в несколько категорий. Хотелось бы понимать плюсы и минусы того или иного варианта. Не то чтобы я хочу создать Amazon, но обучения ради.
И насколько это сложно или легко будет использовать в ORM Laravel.
Может быть какие-то уроки по разработке более-менее гибкого и-магаза в Laravel.
  • Вопрос задан
  • 3964 просмотра
Пригласить эксперта
Ответы на вопрос 4
@asd111
MongoDB или jsonb в PostgreSQL и никаких мучений с проектированием.
Ответ написан
@m0nym
EAV - штука дико медленная. Для хранения и редактирования - удобна, логична.
Но отдавать из нее информацию на запросы пользователя - это плохо, медленно.

Для работы с фильтрами лучше подходят специализированные СУБД фасеточного поиска, а не классические реляционные СУБД типа MySQL
Фасеточный (а заодно и полнотекстовый) поиск - это, к примеру, SphinxSearch, ManticoreSearch, ElasticSearch и т.п.
Ответ написан
Rastishka
@Rastishka
Вряд ли это правильный паттерн, но я делал так:
В таблице куча столбцов вида v1, v2, v3, v4 (varchar), i1,i2,i3 (int)......
Для каждой категории массив связок типа 'color' => 'v2', 'radius' => 'i1'
В модельках через сеттеры, геттеры и скоупы это все преобразуется в человекочитаемый вид.
Ответ написан
@Viktor_Dav
Если я правильно понял вопрос, можно использовать промежуточные таблицы.
Таблицы:

ITEM
id | name
1 | t-shirt
2 | polo shirt
3 | jeans

CATEGORY
id | name
1 | top
2 | bottom

ATTRIBUTE
id | name
1 | size
2 | inseam
3 | waist

ITEM_CATEGORY
id | item_id | category_id
1 | 1 | 1
2 | 2 | 1
3 | 3 | 2

ITEM_ATTRIBUTE
id | item_id | attribute_id | value (или value_id если атрибуты определены)
1 | 1 | 1 | XL
2 | 2 | 1 | M
3 | 3 | 2 | 34
4 | 3 | 3 | 32

На практике, скорее всего, пригодятся также полиморфные связи, когда в одном столбце могут храниться ссылки на строки, принадлежащие разным таблицам. Для этого в исходную таблицу добавляется столбец type, где хранится тип (к какой таблице обращаться), а в другом столбце хранится id строки в этой таблице.
В таблицу ITEM_ATTRIBUTE уже можно добавить столбец type, чтобы хранить и ссылки на строки в разных таблицах, где перечисляются значения атрибутов (например добавить таблицу TOP_SIZE_VALUE и пихать не строку, а ссылку) и строки.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

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