Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що таке модель EAV і чому її уникають?

EAV (Entity-Attribute-Value) - зберігати довільні атрибути не колонками, а рядками «сутність - атрибут - значення»:

product_attributes: product_id | attribute | value
                    1          | color     | red
                    1          | weight    | 1.2
                    2          | voltage   | 220

Привабливо для товарів з різними характеристиками (одяг має розмір, а холодильник - об'єм): нові атрибути додаються без зміни схеми. Так влаштований, наприклад, Magento.

Чому EAV уникають:

  • Немає типів: value - текст для всього. Числа порівнюються як рядки ('10' < '9'), дати - теж, і будь-яке значення можна записати в будь-який атрибут.
  • Немає обмежень: NOT NULL, діапазони, зовнішні ключі для значень - неможливо описати базою.
  • Запити жахливі: «червоні товари вагою до 2 кг» - кілька самоз'єднань тієї самої таблиці чи GROUP BY з умовами в HAVING. Кожен новий фільтр - ще один JOIN.
  • Продуктивність падає з ростом таблиці атрибутів, а індекси допомагають слабо.
  • Звіти й аналітика вимагають «розвертати» рядки в колонки.

Альтернативи:

  • jsonb для змінних атрибутів - найчастіша сучасна заміна:
CREATE TABLE products (
    id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
    name text NOT NULL,
    price numeric(10, 2) NOT NULL,      -- спільні поля - звичайні колонки
    attributes jsonb NOT NULL DEFAULT '{}'
);

SELECT * FROM products WHERE attributes @> '{"color": "red"}';

Зберігаються типи JSON (числа - числами), є GIN-індекси, документ читається одним рядком.

  • Окремі таблиці для типів сутностей (наслідування таблиць: спільна products + product_clothing, product_appliances), коли типів небагато і їхні атрибути стабільні.
  • Звичайні колонки - якщо атрибутів насправді десяток і вони відомі заздалегідь.

Коли EAV ще має сенс: атрибути визначають самі користувачі в адмінці, їх тисячі, і потрібна метаінформація про кожен атрибут (тип, одиниці, порядок показу). Тоді EAV роблять з типізованими колонками значень (value_int, value_text, value_date) і таблицею-описом атрибутів.

Докладніше в документації: Entity-attribute-value model

Схожі питання