Друкарня від WE.UA

Коли використовувати JSONB у реляційній БД?

1. Історичний зліпок (Snapshot) зовнішніх API

Проблема: Ви інтегруєтесь із зовнішнім сервісом, чий API змінюється кожні кілька місяців.

  • Невдале рішення (підтаблиці): Постійні ALTER TABLE, додавання полів, які для старих записів залишаються NULL. Втрачається контекст: як саме виглядав об'єкт на момент запиту.

  • Гарне рішення (JSONB):

CREATE TABLE api_journal (
    id BIGINT,
    request JSONB,  -- ідентична копія надісланих даних
    response JSONB  -- ідентична копія отриманої відповіді
);

Перевага: Підтримка різних версій схеми даних без міграцій та збереження повної цілісності історичних даних.


2. Різнорідні події зі змінною структурою

Проблема: Система аудиту фіксує події, кожна з яких має унікальний набір атрибутів.

  • Невдале рішення: Створювати «таблицю-простирадло» з 50+ nullable-полями або городити десятки окремих таблиць під кожен тип події.

  • Гарне рішення:

CREATE TABLE audit_log (
    id BIGINT,
    event_type VARCHAR(50),
    event_data JSONB  -- гнучка структура атрибутів
);
CREATE INDEX idx_event_data ON audit_log USING GIN (event_data);

Запит (знайти платежі > 1000):

SELECT * FROM audit_log 
WHERE event_type = 'payment_created' 
  AND (event_data->>'amount')::numeric > 1000;

3. Списки вкладених об'єктів (Denormalization)

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

  • Невдале рішення: Виносити кожну дрібницю в окрему таблицю. Це змушує використовувати JOIN, що при великій кількості записів може сповільнювати систему та ускладнювати мапінг в коді.

  • Гарне рішення:

CREATE TABLE cards (
    id BIGINT,
    pan_mask VARCHAR(19),
    fraud_marks JSONB  -- масив об'єктів в одному полі
);

Пошук активних міток:

SELECT * FROM cards WHERE fraud_marks @> '[{"active": true}]';

4. Кеш та тимчасові дані (TTL)

Проблема: Дедуплікація запитів або збереження результатів обчислень на короткий час.

  • Невдале рішення: Створювати складну схему з Foreign Keys. При видаленні застарілих даних (Cleanup) потрібно враховувати порядок видалення через обмеження цілісності.

  • Гарне рішення:

CREATE TABLE dedup_cache (
    key VARCHAR(255) PRIMARY KEY,
    cached_data JSONB,
    expires_at TIMESTAMP
);

Очищення даних: Виконується однією операцією DELETE без ризику порушити зв'язки.


5. Збереження контексту помилок

Проблема: Для дебагу потрібно зберігати Stack Trace та стан об'єктів у момент виникнення Exception.

  • Невдале рішення: Зберігати все як TEXT. Його неможливо ефективно фільтрувати або аналізувати програмно.

  • Гарне рішення:

CREATE TABLE error_logs (
    id BIGINT,
    error_details JSONB -- клас помилки, стектрейс, контекст (user_id, env)
);

6. Конфігурації модулів

Проблема: Різні компоненти системи мають абсолютно різні налаштування (ліміти, ендпоінти, прапорці).

  • Невдале рішення: Паттерн EAV (Entity-Attribute-Value). Складно збирати об'єкт докупи, важко зберігати масиви та вкладеність.

  • Гарне рішення: Зберігати конфігурацію як єдиний JSON-об'єкт. Це дозволяє за один запит отримати всі налаштування модуля в їх природній ієрархічній структурі.


Коли НЕ варто використовувати JSONB:

  1. Критичні бізнес-сутності: Користувачі, замовлення, товари. Тут потрібна строга нормалізація, Foreign Keys та обмеження на рівні схеми.

  2. Масова агрегація: Функції на кшталт SUM, AVG, GROUP BY по полях всередині JSONB працюють значно повільніше, ніж по звичайних колонках.

  3. Часті апдейти: При оновленні навіть одного поля в JSONB, СКБД фактично переписує весь об'єкт. Якщо поле змінюється щосекунди — використовуйте звичайну колонку.

  4. Важливість суворої типізації: Якщо бізнес-логіка вимагає гарантії наявності поля та його типу на рівні БД.

Підсумок

JSONB — це ідеальний баланс між:

  • EAV: занадто гнучко, складно для запитів.

  • Жорсткою схемою: занадто консервативно, вимагає постійних міграцій.

Використовуйте JSONB для Snapshot-ів, поліморфних логів, метаданих та конфігурацій.


Статті про вітчизняний бізнес та цікавих людей:

  • CRM keyCRM: зручне рішення для продажів, комунікацій і керування командою

    Успіх компанії залежить від того, наскільки швидко вона здатна опрацьовувати вхідні запити. Коли дані про клієнтів розпорошені між різними месенджерами, виникає хаос. CRM keyCRM пропонує вихід із цієї ситуації, об’єднуючи всі робочі процеси в єдиному зручному інтерфейсі.

    Теми цього довгочиту:

    Crm
  • Різниця між UX і UI, яку варто зрозуміти ще до першого заняття

    Більшість людей, які обирають професію UX чи UI, довго вважають це одним і тим самим. Насправді це два різних підходи до роботи над продуктом, і плутанина між ними гальмує розвиток ще на старті.

    Теми цього довгочиту:

    Ui-ux
  • Логіка змін: як SEO оптимізація прибирає бар’єри до зростання

    Багато компаній приходять у SEO з очікуванням швидкого ривка, але дійсний ефект починається там, де сайт перестають латати точково. Тому в центрі роботи стоїть не окрема дія, а послідовні зміни. Оптимізація сайту має прибирати системні перешкоди, а не маскувати їх новими текстами

    Теми цього довгочиту:

    Seo
  • Музичний футуризм: неймовірні інструменти XXI століття

    Еволюція музичних інструментів це один із найкрутіших проявів потужності людської уяви і потреби виразити себе через мистецтво. І хоча багато традиційних інструментів майже не змінилися за століття існування, інновації і пошук не зупиняються.

    Теми цього довгочиту:

    Музичні Інструменти
  • Стіл – всьому голова? Так, якщо його правильно підібрати

    Коли починаєш вивчати пропозицію меблевих фабрик щодо столів, дивуєшся кількості варіантів, адже вони пропонують різні розміри, різні матеріали, різноманітні форми та дизайни. Скористайтесь нашим каталогом MebelOK, щоб Ви могли підібрати найкращу модель для Вашого приміщення

    Теми цього довгочиту:

    Столи
Поділись своїми ідеями в новій публікації.
Ми чекаємо саме на твій довгочит!
Oleksandr Klymenko
Oleksandr Klymenko@overpathz

Java Software Engineer

40Довгочити
8.9KПерегляди
101Підписники
На Друкарні з 19 квітня 2023

Більше від автора

Це також може зацікавити:

Коментарі (0)

Підтримайте автора першим.
Напишіть коментар!

Це також може зацікавити: