Pull to refresh

Comments 9

Был у меня опыт работы с EAV, это была боль, по мере роста количества данных - росло время выборок. В базе было порядка 50 000 моделей, 2-3 дюжены атрибутов и у каждого до 10 значений, итого - порядка 600 000 записей в таблице.

В итоге пришлось переписать всё, переведя хранение данных в jsonb поле в постгрессе, скорость выборок на сложных запросах упала с десятков секунд, до десятых долей секунды.

Да, jsonb это убойная фича Постгреса.

У вас было 600к значений, на моём наборе данных их 800к+600к = 1,4кк. У вас 50к моделей, у меня всего 29к, но разница в два раза для таких значений уже несущественна.

Если выборка идёт за десятые доли секунды, то это сотни миллисекунды, у меня в измерениях максимум десятки миллесекунд, то есть работа с таблицей выигрывает у работы с jsonb на порядок.

Но конечно для работы с jsonb не надо такой огород городить как у меня, но с другой стороны, когда кто то уже сделал инструмент, почему бы и нет ?

Попробую написать бенчмарк для jsonb, спасибо за идею.

Потому что EAV не сможет дать такие же эффективные запросы, как JSONB. Простой пример - есть продукты, у продуктов есть какие-то атрибуты с какими-то значениями.

Задача - выбрать все продукты у которых есть два атрибута - A и B.

В случае JSONB - это будет один WHERE. В случае EAV - JOIN или GROUP BY.

Дополнительно можно сравнить производительность, если не два атрибута, а 10 или 20.

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

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

У меня в бенчмарке замеряется выборка по 46 колонкам для первого случая, об этом написано в статье.

Для второго случая 14, для третьего 2. Хотел это добавить в статью, но редактор выдаёт 400 ошибку. Пришлось оставить как есть.

Jsonb не может дать такие же эффективные запросы, потому что это запросы к упакованным в одну колону данным, а не к отдельным колонкам, как в моей библиотеке. Будет или так же или медленей.

То есть при добавлении нового атрибута вы в таблицу добавляете еще однин столбец? Логично что разных атрибутов будет не n тысяч и в ограничение столбцов не упремся. Решаем сейчас заново похожую задачу (работающий в проде вариант - join + count), только дополнительно у нас атрибуты группируются в группы атрибутов и уже группа атрибутов используется для идентификации сущности. Интересно было прочитать про ваш подход и выводы. У нас несколько бОльшие объемы по числу сущностей и пока рабочей версией является отказ от фильтрации средствами бд. Из плюсов - полностью предсказуемая и стабильная скорость поиска.

Отказ от фильтрации на стороне СУБД это очень смелый шаг.

Для фильтрации средствами приложения вы должны всё выгрузить из СУБД в память приложения и дальше без каких либо индексов, делать выборку.

Я не знаю .. in-memory СУБД тогда уж применяйте, если вам оперативной памяти не жалко. Тарантул например.

Почитайте о jsonb, посмотрите доклад Олега Бартунова с последнего хайлрада, в постгресе очень сильно поработали над jsonb, это очень сильный инструмент.

По полям внутри json можно построить индекс, выборка производиться при использовании этого индекса. К полям внутри json можно применять такие же операции сравнения как к обычным колонкам.

Вам только придётся научиться со всем этим работать. Но оно того стоит.

Если вам интересна идея моей библиотеки, то у меня в профиле посмотрите другие статьи по "Универсальному каталогу". Мне кажется я очень подробно описал идею.

Следующая статья будет с примером использования.

У нас не только постгре, но и mssql (не свежих версий), и сдается мне что индекс по json и индекс по xml(в mssql) суть похожи, тоесть нужно в динамический запрос добавлять все искомые атрибуты и план будет страшен + всё равно с диска поднимать данные.

Inmemory базы всё равно не объектно орентированные, математика там та же. Если только хитрые колоночные хранилища, которые и в постгре есть, а в сиквеле в этой задаче местами давали невероятные ускорения. В inmemory db тоже нужно грузить, прогрев очень долгий, на первом этапе у нас 600м сущностей грузятся десятки минут. Кроме того, самопалом можно схитрить, и ,например, 600м intов утолкать в 100мб памяти. Пока мы решили своими силами, посмотрим. Первый проект с такой организацией поехал в прод перед новым годом.

ЕАВ - хранилище с динамической структурой (персисентная часть характеристик - свойств и временные характеристики - свойства).

Со временем структура (стремиться стать) становится статической.

Классификация идет не только по свойствам, но и по их значениям.

Малое количество определенных значений (когда значения свойства для всех объектов определены) разбивает тип на тип с подтипами.

Малое количество определенных значений хранятся в жесткой структуре ЕАВ (там редко применяется поиск, так как эти свойства не устойчивы (в основном нулл для большинство объектов типа)), по мере роста количество определенных значений свойства для объектов типа свойство переносится в персистентную часть и так же обртано - увеличение количество непопределенных значений приводит к переносу свойства во временный отстойник.

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

Sign up to leave a comment.

Articles