JavaRush /Курси /SQL SELF /Порівняння JSON з іншими типами: ARRAY,

Порівняння JSON з іншими типами: ARRAY, TEXT, HSTORE

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

У PostgreSQL багато розробників стикаються з вибором: яку структуру даних юзати для зберігання інфи? Використовувати масиви (ARRAY) для простішої структури? Чи текстові (TEXT) колонки для рядків? А може, HSTORE для зберігання пар "ключ-значення"? Ну і, звісно, виникає питання: а коли все ж краще JSON або JSONB?

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

Коли юзати масиви (ARRAY), а коли JSONB?

Масиви (ARRAY) ідеально підходять для даних, які є однорідними наборами значень. Наприклад, якщо у тебе є список оцінок студентів або теги для запису, масиви — саме те.

Приклад масиву:

CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades INTEGER[] -- масив оцінок
);

INSERT INTO students (name, grades)
VALUES ('Аліса', ARRAY[90, 85, 88]),
       ('Боб', ARRAY[70, 75, 78]);

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

Приклад JSONB:

CREATE TABLE students_json (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades JSONB -- об'єкт з даними про оцінки
);

INSERT INTO students_json (name, grades)
VALUES ('Аліса', '{"Математика": 90, "Наука": 85, "Англійська": 88}'),
       ('Боб', '{"Математика": 70, "Наука": 75, "Англійська": 78}');

Основні відмінності

Критерій Масиви (ARRAY) JSONB
Структура Однорідні дані одного типу Складні вкладені структури даних
Доступ до даних За індексом: grades[1] За ключем: grades->'Математика'
Підтримка індексів Тільки GIN або BTREE для всього масиву Зручні GIN і BTREE індекси по ключах
Коли використовувати Прості списки даних (теги, оцінки, ідентифікатори) Складні об'єкти з ключами і значеннями

Приклади перетворення з масиву в JSONB і навпаки

Давай подивимось, як можна перетворювати дані між масивами і JSONB:

Масив → JSONB

SELECT to_jsonb(grades) AS grades_jsonb
FROM students;

-- Результат:
-- [{"90","85","88"}]

JSONB → Масив

SELECT array_agg(value::INTEGER) AS grades_array
FROM jsonb_array_elements_text('["90", "85", "88"]');
-- Результат:
-- {90,85,88}

Порівняння JSONB і текстових даних (TEXT)

Текстові колонки ідеальні, якщо треба просто зберігати рядки тексту або невеликі неструктуровані дані. Якщо твоя задача — пошук по співпадінню рядків, наприклад, у назві продукту чи описі, TEXT — твій вибір.

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title TEXT,
    description TEXT
);

INSERT INTO books (title, description)
VALUES ('Основи SQL', 'Короткий вступ до SQL'),
       ('Поглиблений PostgreSQL', 'Детальний гайд по продуктивності PostgreSQL');

Коли краще юзати JSONB?

Якщо твій рядок перетворюється на інфу з вкладеною структурою (наприклад, опис з вкладеною категорією і списком тегів), краще обирати JSONB.

CREATE TABLE books_json (
    id SERIAL PRIMARY KEY,
    info JSONB
);

INSERT INTO books_json (info)
VALUES ('{"title": "Основи SQL", "tags": ["початківець", "база даних"]}'),
       ('{"title": "Поглиблений PostgreSQL", "tags": ["продуктивність", "оптимізація"]}');

Основні відмінності

Критерій Текст (TEXT) JSONB
Структура Неструктуровані дані Структуровані, вкладені дані
Пошук Повнотекстовий пошук Пошук по ключах, значеннях, вкладеній структурі
Зміна даних Тільки повна заміна Зміна окремих ключів
Коли використовувати Прості рядки тексту Складні дані у форматі ключ-значення

Порівняння JSONB і HSTORE

HSTORE — це старший брат JSONB, який дозволяє зберігати пари "ключ-значення". Наприклад, якщо твоя структура даних проста (не треба вкладеності і масивів), HSTORE буде легшим і швидшим.

CREATE TABLE products (
    id SERIAL PRIMARY KEY,
    attributes HSTORE
);

INSERT INTO products (attributes)
VALUES ('"колір"=>"червоний", "розмір"=>"M"'),
       ('"колір"=>"синій", "розмір"=>"L"');

Чому JSONB замінив HSTORE?

Хоч HSTORE зручний для пар "ключ-значення", він не підтримує вкладеність і масиви, що робить JSONB більш універсальним. Якщо ти виріс із простих об'єктів, JSONB стає природним наступним кроком.

Основні відмінності

Критерій HSTORE JSONB
Структура Пари "ключ-значення", без вкладеності Повноцінні вкладені структури
Підтримка масиву Ні Так
Пошук Тільки по ключу По ключах, значеннях, вкладеній структурі
Коли використовувати Прості ключ-значення Складні структури даних

Як обрати підходящий тип даних?

Якщо у тебе:

  • Проста структура — списки або однорідні дані, юзай масиви (ARRAY).
  • Прості рядки або описи, юзай текстові колонки (TEXT).
  • Пари "ключ-значення" без вкладеності, обирай HSTORE.
  • Вкладені об'єкти і масиви, складна структура даних — тобі потрібен JSONB.

Приклади перетворення між форматами

TEXT → JSONB

SELECT to_jsonb('Простий приклад тексту') AS jsonb_form;
-- Результат: "Простий приклад тексту"

JSONB → TEXT

SELECT info::TEXT AS text_form
FROM books_json;
-- Результат: {"title": "Основи SQL", "tags": ["початківець", "база даних"]}

HSTORE → JSONB

SELECT hstore_to_jsonb(attributes) AS jsonb_form
FROM products;
-- Результат: {"колір": "червоний", "розмір": "M"}

JSONB → HSTORE

SELECT jsonb_to_hstore('{"колір": "червоний", "розмір": "M"}') AS hstore_form;
-- Результат: "колір"=>"червоний", "розмір"=>"M"

На що звернути увагу?

Якщо потрібна максимальна гнучкість і підтримка складних структур, обирай JSONB. Але якщо твоя задача — це прості структури даних, такі як масиви, текст або пари "ключ-значення", юзай відповідні типи даних (ARRAY, TEXT, HSTORE).

Не забувай, що правильний вибір структури даних допоможе уникнути головного болю на наступних етапах розробки і підвищить продуктивність твоїх запитів.

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