Re: Как лучше использовать РСУБД для данных с динамической струк
От: Sinclair Россия https://github.com/evilguest/
Дата: 04.10.18 07:39
Оценка: 12 (2) +1
Здравствуйте, vsb, Вы писали:

vsb>Например есть разные типы сущностей, у них разные дополнительные поля (к примеру витрина в магазине, типов товаров может быть очень много вплоть до разделения "процессор", "оперативная память" и тд) и у каждого типа могут быть свои характеристики, по которым потенциально может быть необходимо сортировать, фильтровать и тд. Как для такой задачи лучше организовать схему БД?

Ключевое — выделено. Наличие либо отсутствие этого пункта радикально влияет на применимость решений.
Без фильтрации можно смотреть в сторону неструктурированных хранилищ. Холиварить не хочу, поэтому тут не очень важно — монго это будет или JSON в nvarchar(max).

Если нужна фильтрация — то забудьте про NoSQL, всех советчиков посылайте лесом: у вас каждая операция будет упираться в full scan. Он будет прекрасно работать на тестовых объёмах, а в продакшне ляжет, а вам будут рассказывать о том, как зато легко это можно победить, подняв 1024 реплики базы в клауде. Тут поможет только нормальное структурированное хранилище.

Филигранить структуру таблиц я бы не советовал — во-первых, быстро упрётесь в ограничения СУБД (они только кажутся большими), во-вторых, зафиксировать "тип товара" удаётся довольно-таки редко. Как правило, реальный товар — это вялый конгломерат каких-то атрибутов, и даже внутри одного типа у вас будет множество атрибутов со значением "не задано". Иногда — потому, что оператор поленился прочитать внимательно сайт производителя, иногда — потому что для данного подвида товара конкретно этот атрибут нерелевантен.

Поэтому выносить в "настоящие" колонки можно только самые-самые популярные атрибуты, ну, и те, которые обязательные (вроде названия и артикула).
Всю остальную кунсткамеру выносите в таблицу атрибутов.
Да, серверу делать по ней многоатрибутную фильтрацию — чуть сложнее, чем для фильтрации по настоящим колонкам.
Хуже работает предсказание селективности, приводя, возможно, к неоптимальному порядку выполнения джойнов. Один хрен, это будет быстрее, чем full scan.

Вообще, по идее, эту задачу не решал только ленивый — наверняка, если порыть интернет внимательно, где-то есть открытый код, который решает типовые задачи для "каталога товаров на EAV":
— собрать entity по её ID
— сравнить N entities, возвращая только различающиеся атрибуты
— найти все entity по заданным значениям (или предикатам) для заданных атрибутов
— найти все значения для заданного атрибута, по убыванию "встречаемости"
— получить список атрибутов для данного типа сущности, отсортированный по убыванию популярности
— итд
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.