Здравствуйте, vsb, Вы писали:
vsb>Например есть разные типы сущностей, у них разные дополнительные поля (к примеру витрина в магазине, типов товаров может быть очень много вплоть до разделения "процессор", "оперативная память" и тд) и у каждого типа могут быть свои характеристики, по которым потенциально может быть необходимо сортировать, фильтровать и тд. Как для такой задачи лучше организовать схему БД?
Ключевое — выделено. Наличие либо отсутствие этого пункта радикально влияет на применимость решений.
Без фильтрации можно смотреть в сторону неструктурированных хранилищ. Холиварить не хочу, поэтому тут не очень важно — монго это будет или JSON в nvarchar(max).
Если нужна фильтрация — то забудьте про NoSQL, всех советчиков посылайте лесом: у вас каждая операция будет упираться в full scan. Он будет прекрасно работать на тестовых объёмах, а в продакшне ляжет, а вам будут рассказывать о том, как зато легко это можно победить, подняв 1024 реплики базы в клауде. Тут поможет только нормальное структурированное хранилище.
Филигранить структуру таблиц я бы не советовал — во-первых, быстро упрётесь в ограничения СУБД (они только кажутся большими), во-вторых, зафиксировать "тип товара" удаётся довольно-таки редко. Как правило, реальный товар — это вялый конгломерат каких-то атрибутов, и даже внутри одного типа у вас будет множество атрибутов со значением "не задано". Иногда — потому, что оператор поленился прочитать внимательно сайт производителя, иногда — потому что для данного подвида товара конкретно этот атрибут нерелевантен.
Поэтому выносить в "настоящие" колонки можно только самые-самые популярные атрибуты, ну, и те, которые обязательные (вроде названия и артикула).
Всю остальную кунсткамеру выносите в таблицу атрибутов.
Да, серверу делать по ней многоатрибутную фильтрацию — чуть сложнее, чем для фильтрации по настоящим колонкам.
Хуже работает предсказание селективности, приводя, возможно, к неоптимальному порядку выполнения джойнов. Один хрен, это будет быстрее, чем full scan.
Вообще, по идее, эту задачу не решал только ленивый — наверняка, если порыть интернет внимательно, где-то есть открытый код, который решает типовые задачи для "каталога товаров на EAV":
— собрать entity по её ID
— сравнить N entities, возвращая только различающиеся атрибуты
— найти все entity по заданным значениям (или предикатам) для заданных атрибутов
— найти все значения для заданного атрибута, по убыванию "встречаемости"
— получить список атрибутов для данного типа сущности, отсортированный по убыванию популярности
— итд
Уйдемте отсюда, Румата! У вас слишком богатые погреба.