Концепция EAV — Entity-Attribute-Value универсальное хранение данных кратко

Лекция



Привет, Вы узнаете о том , что такое концепция eav, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое концепция eav, entity-attribute-value , настоятельно рекомендую прочитать все из категории Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL.

Соблазн использовать модель EAV ( entity-attribute-value ) при организации структуры БД весьма велик, особенно когда предметная область заранее плохо известна (или разработчик просто не хочет в нее углубляться). Это ведь так удобно - создать "универсальный" способ описания характеристик объектов, который больше не потребует доработок базы ни при появлении новых типов объектов, ни при возникновении новых атрибутов...

традиционные реляционные базы данных являются специализированными для предметной области или НЕуниверсальными.
Признаки неуниверсальных структур БД:
  1. Каждая таблица базы данных соответствует определенной сущности предметной области
  2. Каждая запись в таблице соответствует определенному экземпляру сущности
  3. Каждое поле таблицы соответствует определенному атрибуту определенного экземпляра определенной сущности

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

Однако, за любую универсальность приходится платить сложностью и производительностью запросов - так что json[b] может оказаться более эффективной заменой. Но если уж такая модификация невозможна - давайте попробуем выжать максимум производительности из доставшегося нам legacy на самом простом примере.

Концепция EAV — Entity-Attribute-Value универсальное хранение данных

Ограничимся работой с единственной таблицей значений:

CREATE TABLE tst_eav AS
SELECT
  (random() * 1e4)::integer e -- 10k объектов
, (random() * 1e2)::integer a -- 100 характеристик
, (random() * 1e2)::integer v -- 100 вариантов значений
FROM
  generate_series(1, 1e6);    -- 1M записей о значениях

Попробуем найти такие объекты e, для которых одновременно существуют записи с (a, v) = (1, 1) и (a, v) = (2, 2) - это типичный вариант множественного фильтра в любом интернет-магазине: "смартфоны с экраном 6" и памятью 64GB".

JOIN

Самым первым вариантом решения, пришедшим в голову разработчика уровня "я уже освоил SQL!", наверняка, будет соединение:

SELECT
  e
FROM
  tst_eav r1
JOIN
  tst_eav r2
    USING(e)
WHERE
  (r1.a, r1.v) = (1, 1) AND
  (r2.a, r2.v) = (2, 2);

Очевидно, для этого нам понадобится, как минимум, индекс по (a, v):

CREATE INDEX eav_idx1 ON tst_eav(a, v);

Посмотрим, что у нас получится в плане:

Концепция EAV — Entity-Attribute-Value универсальное хранение данных

JOIN'им два набора строк

Сначала отбор по одной паре значений и сортировка по e, потом - по второй паре и сортировка, а потом уже - слияние двух отсортированных наборов.

Этот вариант станет для нас отправной точкой: 432мкс + 207 buffers.

Неплохо для отбора из миллиона записей, но можно лучше!

INTERSECT

Ведь в предыдущем запросе мы искали вовсе не соединение, а пересечение множеств - так давайте его и попробуем использовать:

  SELECT
    e
  FROM
    tst_eav
  WHERE
    (a, v) = (1, 1)
INTERSECT
  SELECT
    e
  FROM
    tst_eav
  WHERE
    (a, v) = (2, 2);

Концепция EAV — Entity-Attribute-Value универсальное хранение данных

INTERSECT'им наборы

А в плане теперь все получше - читаем ровно столько же, зато не пришлось тратить время на две сортировки: 301мск + 207 buffers.

GROUP BY

А можно как-то читать меньше данных? В принципе, да - ведь у нас дважды происходит чтение страниц данных по маске - сначала для одного условия, потом для другого. Об этом говорит сайт https://intellect.icu . А избежать этого можно с помощью группировки, читая все за один раз:

SELECT
  e
FROM
  tst_eav
WHERE
  (a, v) IN ((1, 1), (2, 2))
GROUP BY
  e
HAVING
  count(*) = 2; -- присутствуют оба условия

Концепция EAV — Entity-Attribute-Value универсальное хранение данных

GROUP BY сразу пары условий

Сэкономили "копеечку": 296мкс + 202 buffers.

Конечно, тут мы пошли на допущение, что каждая пара (a, v) внутри одного объекта заведомо уникальна. Потому что если это не так, запрос станет существенно сложнее:

SELECT
  e
FROM
  tst_eav T
WHERE
  (a, v) IN ((1, 1), (2, 2))
GROUP BY
  e
HAVING
  array_length(array_agg(DISTINCT T), 1) = 2; -- оба уникальных условия

INCLUDE

Но всегда терзает мысль - может быть, можно сделать запрос еще быстрее?.. Оказывается, в нашем случае - можно!

Заметим, что львиная доля времени уходит на Bitmap Heap Scan - то есть вычитку страниц таблицы ради получения значения e, ведь его нет в нашем индексе, иначе мы могли бы обойтись Index Only Scan.

Но ведь еще с PostgreSQL 11 есть способ добавить неключевые поля в индекс:

CREATE INDEX eav_idx2 ON tst_eav(a, v) INCLUDE(e);

Концепция EAV — Entity-Attribute-Value универсальное хранение данных

INCLUDE избавляет от Bitmap Heap Scan

И вот теперь наш план для INTERSECT-варианта: 121мкс + 9 buffers.

А ведь чем меньше страниц данных (buffers) читается, тем меньше шансов сходить за ними на диск и потерять в скорости.

Исследование, описанное в статье про концепция eav, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое концепция eav, entity-attribute-value и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL

Из статьи мы узнали кратко, но содержательно про концепция eav
создано: 2026-02-25
обновлено: 2026-03-09
20



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


Поделиться:
Пожаловаться

Найди готовое или заработай

С нашими удобными сервисами без комиссии*

Как это работает? | Узнать цену?

Найти исполнителя
$0 / весь год.
  • У вас есть задание, но нет времени его делать
  • Вы хотите найти профессионала для выполнения задания
  • Возможно применение функции гаранта на сделку
  • Приоритетная поддержка
  • идеально подходит для студентов, у которых нет времени для решения заданий
Готовое решение
$0 / весь год.
  • Вы можете продать (как исполнитель) или купить (как заказчик) готовое решение
  • Вам предоставят готовое решение
  • Будет предоставлено в минимальные сроки т.к. задание уже готовое
  • Вы получите базовую гарантию 8 дней
  • Вы можете заработать на материалах
  • подходит как для студентов так и для преподавателей
Я исполнитель
$0 / весь год.
  • Вы профессионал своего дела
  • У вас есть опыт и желание зарабатывать
  • Вы хотите помочь в решении задач или написании работ
  • Возможно применение функции гаранта на сделку
  • подходит для опытных студентов так и для преподавателей

Комментарии

Оставить комментарий

Если у вас есть какое-либо предложение, идея, благодарность или комментарий, не стесняйтесь писать. Мы очень ценим отзывы и рады услышать ваше мнение.
To reply

Лекции и учебник по "Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL"

Термины: Базы данных, знаний и хранилища данных. Big data, СУБД и SQL и noSQL