JavaRush /Курси /SQL SELF /Порівняння JSON і JSONB: пере...

Порівняння JSON і JSONB: переваги та недоліки кожного формату

SQL SELF
Рівень 33 , Лекція 1
Відкрита

Одне з ключових відмінностей між JSON і JSONB полягає у форматі зберігання даних. JSON зберігає дані у вигляді тексту, а JSONB — у бінарній формі. Це означає, що:

  • JSON зберігає дані саме так, як ти їх передав. Наприклад, якщо ти вставляєш рядок {"title": "PostgreSQL", "tags": ["database", "SQL"]}, він буде збережений як є.
  • JSONB спочатку парсить JSON-об'єкт, видаляє зайві пробіли, впорядковує ключі, оптимізує структуру і тільки потім зберігає її у бінарному форматі.

Ця оптимізація дозволяє JSONB швидше працювати з даними, особливо при виконанні складних запитів на фільтрацію, пошук і сортування.

Продуктивність операцій читання і запису

JSON і JSONB мають різні характеристики по швидкості читання і запису даних:

  • JSON швидше записується в базу, бо немає потреби парсити дані перед збереженням. Але читання і обробка таких даних зазвичай повільніші, бо PostgreSQL під час виконання запитів має заново парсити дані.
  • JSONB потребує більше часу на запис, бо перед збереженням дані проходять обробку. Але читання даних, їх фільтрація і витягування значень відбуваються значно швидше, що робить JSONB кращим для аналітичних чи пошукових задач.

Приклад для наочності:

-- Створення таблиць з JSON і JSONB
CREATE TABLE json_example (data JSON);
CREATE TABLE jsonb_example (data JSONB);

-- Вставка даних
INSERT INTO json_example VALUES ('{"key": "value", "tags": ["json", "example"]}');
INSERT INTO jsonb_example VALUES ('{"key": "value", "tags": ["jsonb", "example"]}');

-- Фільтрація даних
SELECT * FROM json_example WHERE data->'key' = '"value"';  -- Повільніше
SELECT * FROM jsonb_example WHERE data->'key' = '"value"'; -- Швидше

Індексація даних

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

Приклад створення індексу:

-- Індекс на JSONB-колонці
CREATE INDEX idx_jsonb_tags ON jsonb_example USING gin (data->'tags');

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

Коли використовувати JSON, а коли JSONB

JSON найкраще підходить для ситуацій, коли:

  • Тобі потрібно зберігати дані у початковому вигляді, без змін.
  • Ти не плануєш активно виконувати запити для фільтрації, пошуку чи сортування по JSON-даним.
  • JSON-дані використовуються переважно для передачі іншим системам чи клієнтам у незмінній формі (наприклад, віддавати фронтенду через API).

Приклад:

-- Зберігання JSON без аналізу
CREATE TABLE api_responses (
    id SERIAL PRIMARY KEY,
    response JSON
);

-- Вставка даних, як вони прийшли від API
INSERT INTO api_responses (response)
VALUES ('{"status": "success", "payload": {"id": 123, "name": "John"}}');

JSONB варто використовувати, якщо:

  • Ти плануєш активно фільтрувати, шукати, групувати чи сортувати дані по значеннях всередині JSON.
  • Продуктивність доступу до даних важливіша за продуктивність запису.
  • Ти хочеш використовувати індексацію для прискорення операцій з JSON-даними.

Приклад:

-- Зберігання JSONB для аналізу і роботи з вкладеними об'єктами
CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    details JSONB
);

-- Вставка даних
INSERT INTO products (details)
VALUES ('{"name": "Laptop", "price": 1200, "tags": ["electronics", "computers"]}');

-- Пошук продуктів з тегом "electronics"
SELECT * FROM products
WHERE details @> '{"tags": ["electronics"]}';

Детальніше про оператори @> і --> ти дізнаєшся у наступних лекціях :P

Приклади роботи з JSON і JSONB

Створимо дві таблиці: одну з JSON-колонкою, іншу з JSONB:

CREATE TABLE json_table (
    id SERIAL PRIMARY KEY,
    data JSON
);

CREATE TABLE jsonb_table (
    id SERIAL PRIMARY KEY,
    data JSONB
);

Вставка даних буде однаковою для обох таблиць:

INSERT INTO json_table (data)
VALUES ('{"key": "value", "tags": ["json", "example"]}');

INSERT INTO jsonb_table (data)
VALUES ('{"key": "value", "tags": ["jsonb", "example"]}');

Тепер спробуємо витягнути дані, де ключ key має значення value:

-- Для JSON
SELECT * FROM json_table
WHERE data->>'key' = 'value';

-- Для JSONB
SELECT * FROM jsonb_table
WHERE data->>'key' = 'value';

Для невеликих обсягів даних різниця у продуктивності буде майже непомітною. Але при роботі з мільйонами рядків JSONB покаже значно кращі результати, особливо якщо ти створиш індекс:

CREATE INDEX idx_jsonb_key ON jsonb_table USING gin ((data->>'key'));

Робота з вкладеними об'єктами і масивами також ефективніша у JSONB:

-- Витягування значення з масиву
SELECT data->'tags'->>0 AS first_tag 
FROM jsonb_table;

Переваги та недоліки

Особливість JSON JSONB
Зберігання даних Зберігає дані у початковому текстовому форматі Зберігає дані у бінарному форматі, впорядковуючи ключі
Продуктивність запису Швидше, бо зберігаються "як є" Повільніше через попередній парсинг
Продуктивність читання Повільніше, бо дані треба парсити під час виконання запиту Швидше, бо дані вже оптимізовані для читання
Індексація Не підтримується Підтримується (індекси GIN, BTREE)
Фільтрація Повільна Швидка
Підтримка операцій Обмежена Розширена

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

Для складних застосунків, де JSON-дані — це не просто "сховище", а й активно використовуються в аналітиці, JSONB стане незамінним інструментом. Тож, якщо вагаєшся — обирай JSONB. Можливо, твій майбутній "найшвидший запит у житті" скаже тобі за це дякую!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ