Как стать автором
Обновить

Комментарии 24

А вот то, что не делали тестов на производительность, да ещё и в течении 3 лет это вы зря. Тем более, что речь о библиотеке которая работает с БД.

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

Современный PostgreSQL имеет JSONB. Который мне кажется будет предпочтительнее к использованию на текущий момент, чем EAV.

А есть сравнение производительности поиска по json (через GIN) и поиска в EAV (где, полагаю, достаточно какого-нибудь хеша)? Ну т.е. например задача, найти все сущности у которых не заполнен (отсутствует значение) атрибут X.

На JSONB (не json) в PostgreSQL можно назначать индексы.

Я знаю, поэтому я и указал в скобках GIN. мой вопрос не про возможность, а про производительность.

В вашем вопросе будет сравниваться производительность индекса с индексом без относительно кто был источником данных (EAV или JSONB — не важно).
Jsonb поддерживает не только GIN индексы (btree и hash также поддерживаются).

Jsonb поддерживает не только GIN индексы (btree и hash также поддерживаются).

Тип jsonb также поддерживает индексы btree и hash. Они полезны, только если требуется проверять равенство JSON-документов в целом. Порядок сортировки btree для типа jsonb редко имеет большое значение, но для полноты он приводится ниже:

В вашем вопросе будет сравниваться производительность индекса с индексом без относительно кто был источником данных (EAV или JSONB — не важно).

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

Производительность EAV схем всегда была ключевой проблемой.

Современный PostgreSQL имеет JSONB. Который мне кажется будет предпочтительнее к использованию на текущий момент, чем EAV.

Из этих утверждений я делаю вывод, что вы считаете реализацию указанной в статье логике через JSONB производительней, чем через EAV. Я прошу вас чем-то подкрепить это утверждение и в качестве примера дал вполне конкретный юзкейс.

Есть ли у вас бенчмарки, которые подтверждают ваши тезисы?

Какие? Если вы на EAV используете btree и его же на JSONB на одних и тех же данных (и если собранная статистика использования схожа), то производительность будет идентична. Вы в этом сомневаетесь?

Из этих утверждений я делаю вывод, что вы считаете реализацию указанной в статье логике через JSONB производительней, чем через EAV.

На своей практике я сталкивался с разными системами реализующие EAV на разных БД (Oracle, DB2, PostgreSQL), а также с PostgreSQL с JSONB.

Что именно выбрать — вопрос критериев. О которых я уже упоминал.
На мой взгляд наиболее эффективным был подход с обычной реляционной структурой для данных у которых структура статична или редко изменяема и вынесением динамической части в JSONB (если речь идет про PostgreSQL).

Но опять таки все зависит от исходных задач и профиля нагрузки на БД — серебренной пули не бывает.

Я прошу вас чем-то подкрепить это утверждение и в качестве примера дал вполне конкретный юзкейс.

В вашем примере заведомо в проигрышной позиции JSONB т.к. для него вы выбрали GIN индекс, тогда как для EAV hash. Если я правильно понял ваш юзкейс.

В вашем примере заведомо в проигрышной позиции JSONB т.к. для него вы выбрали GIN индекс, тогда как для EAV hash. Если я правильно понял ваш юзкейс.

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

Но опять таки все зависит от исходных задач и профиля нагрузки на БД — серебренной пули не бывает.

Современный PostgreSQL имеет JSONB. Который мне кажется будет предпочтительнее к использованию на текущий момент, чем EAV.

Так все таки JSONB или не бывает? Мой вопрос возник именно потому, что изначальное утверждение было достаточно безапелляционным, поэтому мне стали интересны какие-то подтверждения этого тезиса. Потому что на горизонте есть подобного рода задачи.

Производительность EAV схем всегда была ключевой проблемой.

Этот мой тезис был про EAV без относительно JSONB. Если бы у EAV не было проблем с производительностью, то все бы на нем и сидели — никто не любит накатывать DDL в продакшене :)

В своём сообщении я добавил ведь перечисление когда EAV может быть интересен/полезен.

Я вам процитировал документацию постгри, в которой сказано, что другие индексы для JSONB полезны только для прямого сравнения документов, а не поиска по ним

brtee и hash индексы вполне можно делать на конкретные поля в JSONB. Не обязательно сравнивать документы целиком. Пример:
CREATE INDEX publisherhash ON books USING HASH ((data->'publisher'));

Если JSON:
{«tags»: {«nk88»: {«ik37»: «iv161»}}, «publisher»: «XlekfkLOtL», «criticrating»: 3}

То индекс publisherhash идет только на поле «publisher». И позволяет искать только по нему.

CREATE INDEX publisherhash ON books USING HASH ((data->'publisher'));

Это понятно, что так можно, но это кажется несколько расходится с той идеей, что пользователь(оператор) может сам атрибут создать (иначе зачем нам EAV, а не предописанная в коде схема). Создавать индексы по действиям пользователя - я не уверен что хорошая затея, особенно на нагруженной базе.

Если бы у EAV не было проблем с производительностью, то все бы на нем и сидели — никто не любит накатывать DDL в продакшене :)

Ну, это можно решать другим способом, например мастер данные хранить как EAV, а для производительных операций использовать отдельный слой, который будет работать с документами. Такое решение

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

Мы сами в новых задачах склоняемся к тому, чтобы делать документное хранилище как раз из-за того, что с ним гораздо комфортней работать при многих сценариях. А везде, где некомфортно - будут сделаны отдельные слои, которые решат эту проблему более эффективным способом, если необходимо

Да. Всё верно. Сколько не видел EAV всегда в итоге приходили к какому-то гибридному виду.

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

Скажем, пресловутый поиск по параметрам все равно отдается на откуп внешнему поисковому движку

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

Вы заблуждаетесь на счёт EAV, посмотрите замеры в статье «Идеальный каталог, оптимизация выборки данных», ссылки по тексту есть.
Когда мы из EAV делаем таблицу или материализованное представление, то поиск по ним ни как не может быть медленней JSONB.
И главная задача этой библиотеки это создание инфраструктуры для работы с EAV через индивидуальную таблицу для данных которые часто обновляются или для работы через материализованное представление для данных которые обновляются крайне редко.

JSONB затащили в постгрес что бы утереть нос MongoDB и прочим. Почему стали популярны документарные БД? потому что не надо заморачиваться на работу со схемой базы данных, во первых это же надо кроме языка программирования научиться разбираться с DDL, что то понимать в СУБД. Второе надо написать библиотечку для работы с EAV и по пути собрать море граблей.
Правильно что ни кто не это не заморачивается, для стартапов это не нужный риск.
А если ты пишешь код для себя, исключительно из академического интереса, то почему бы и нет.
Мне было интересно проверить концепцию, я её проверил и сделал это ещё три года назад в 2018 году когда написал статью «Идеальный каталог, оптимизация выборки данных».
Разработка библиотеки это ещё одно доказательство в пользу жизнеспособности идеи.
И я думаю что эта идея была реализован и не раз, просто в инхаус системах, поэтому широкой публике не известна.
Только вот у материализированного представления есть свои нюансы.
Любая идея может быть жизнеспособной. Вопрос только в критериях её применимости. Вы же понимаете, что серебренной пули не бывает.
Поэтому (лично мне) в этой статье для большей объективности не хватает:
1. замеров производительности
2. критериев когда EAV уместен, а когда — нет

Не возникало мыслей переписать на джейсон?
На мой взгляд, с появлением его нативной поддержки в датабазах, еав просто умер. Эти ухищрения попросту становятся не нужны.


И сразу задам вопрос, поскольку из текста не совсем понял, а это, на мой взгляд, самая важная проблема при хранении свободных наборов данных: в БД где-то хранится канонический набор свойств для сущности?

У JSON в БД тоже есть минусы (рассматриваем PostgreSQL, как в статье). Например при изменении одного поля в JSON считывать и переписывать нужно весь JSON целиком.

Что лучше зависит от многих факторов:
1. объем данных
2. как часто планируется менять схему
3. количество индексируемых полей
4. соотношение операций чтения к операциям модификации
5. нужен ли (жесткий) контроль над схемой или нет

Но EAV выглядит больше как технология которой удел на малых объемах данных где требуется большая гибкость, частое изменение схемы при том, что нужен и сам контроль над схемой.
JSONB это другой способ решения той же задачи которую решает EAV.
Чисто теоретически, решение через хранение данных в индивидуальных таблицах должно быть быстрее хранения через JSONB. Просто потому что JSONB это куча мала, а таблица это уже распарсенные записи.
По быстродействию в лучшем случаем будет одинаково, а по объёму JSONB больше места занимает, нам надо хранить и сам JSONB и распасенный вариант.
Если вам это интересно, то мы можем вместе написать код и провести замеры.

Увы, я точно не соберусь. Интерес у меня чисто академический.
Я понимаю что джейсон — это куча-мала. Но еав — это наполовину такая же куча-мала, по крайней мере в частности контроля целостности. Для большинства применений (мне из них знаком только поиск по параметрам в интернет-магазине) и то и другое решение работает нормально.

Чтобы EAV стал менее «куча-мала» можно попробовать использовать партициирование по типу сущности. Это даст буст к скорости т.к. индексы будут компактнее и в общем схема станет чуточку ближе к реляционной и всё это будет аккуратно скрыто от клиента.
JSONB это другой способ решения той же задачи которую решает EAV.

Но это же не так. EAV берет на себя задачу по фиксации и контролю за схемой. JSONB этого не позволяет делать.

Общее у них только то, что оба позволяют менять схему данных не изменяя, собственно, схему БД.

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

EAV это способ записи и чтения данных, это не способ контроля целостности, если у сущности 10 атрибутов, а мы создали значения только для пяти, EAV это примет и не выкинет исключения.
Только если мы попытаемся добавить значения для атрибута который не был создан, только тогда у нас будет ошибка. Но и её легко не допустить, если проверять существование атрибута, перед записью, с применением кеша это незначительно утяжелит запрос.
Общее у них только то, что оба позволяют менять схему данных не изменяя, собственно, схему БД.

Как раз моя библиотека и предназначена для того что бы налету менять схему данных. Она делает это прозрачно для клиентской логики. И это будет местом для тюнинга и оптимизаций. Сейчас например при добавлении нового атрибута, таблица целиком пересоздаётся, вместо добавления одно колонки.
EAV это способ записи и чтения данных, это не способ контроля целостности

Это в вашей нотации, тогда нужно давать такое уточнение в статье.
EAV — Entity-Attribute-Value. В самом названии указано — сущность-атрибут-значение, т.е. от схемы к данным. В EAV вы сначала задаете схему и только потом можете писать данные — не наоборот.

И да. Мне кажется, что есть путанница в терминологии? Говоря о схеме я говорил именно о схеме данных (сущность-атрибут), а не про ссылочную целостность между сущностями.

EAV также обычно предоставляет целостность с точки зрения атрибутики (тип атрибута, его мандаторность и т.д.). Нужно это или нет — вопрос требований. Но ничего этого нет у схемы на базе JSONB.

Поэтому да. EAV и JSONB не равнозначные и часто решают разные, хоть и похожие задачи.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории