Одне з ключових відмінностей між 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. Можливо, твій майбутній "найшвидший запит у житті" скаже тобі за це дякую!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ