JavaRush /Курси /SQL SELF /Порівняння масивів і JSONB

Порівняння масивів і JSONB

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

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

Масиви vs JSONB: міні-черепашки даних vs гнучкість у коробці

Ти вже добре знаєш, що в масивах PostgreSQL можна зберігати значення будь-якого одного типу даних: масив чисел, стрічок або дат. Приклад: список оцінок студента, де всі елементи — числа.

-- Таблиця зі студентами та їх оцінками
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT,
    grades INTEGER[]    -- масив оцінок
);

JSONB, на відміну від масиву, — це зберігання даних у вигляді JSON-структури. Це дуже схоже на знайомий усім JavaScript-об'єкт, але з перевагою швидкого парсингу та індексації. В JSONB можна зберігати як впорядковані списки, так і об'єкти з ключами та значеннями.

-- Таблиця зі студентами та різними даними про них
CREATE TABLE students_details (
    id SERIAL PRIMARY KEY,
    name TEXT,
    details JSONB  -- гнучка JSON-структура
);

Приклад даних у JSONB:

{
    "grades": [90, 82, 77],
    "address": {
        "city": "Berlin",
        "zip": "352912"
    }
}

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

Основні відмінності між масивами і JSONB

Ознака Масиви JSONB
Тип структури Лінійна структура даних Ієрархічна структура даних
Типи елементів Тільки один тип даних Різні типи даних
Розмір структури Фіксований (лінійний) Гнучкий, може містити списки і об'єкти
Швидкість доступу Висока при фіксованих даних Повільніше при складних пошуках
Індексація Добре підтримує індексацію Потребує індексації типу GIN
Застосування Простий список або масив значень Складні дані: вкладені об'єкти/лісти

Тепер подивимось, як це все працює на практиці.

Коли використовувати масиви?

Припустимо, у нас є база даних з книжками, де кожна книжка може належати до кількох жанрів. Масив тут буде класним вибором.

CREATE TABLE books (
    id SERIAL PRIMARY KEY,
    title TEXT,
    genres TEXT[]    -- масив жанрів
);

-- Приклад вставки книжки з кількома жанрами
INSERT INTO books (title, genres)
VALUES ('1984', ARRAY['Dystopia', 'Political Fiction', 'Science Fiction']);

Масиви круті, якщо ти впевнений, що:

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

Переваги масивів

  • Простота зберігання однотипних даних.
  • Зручно для невеликих списків, таких як теги, категорії чи оцінки.

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

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

CREATE TABLE books_details (
    id SERIAL PRIMARY KEY,
    title TEXT,
    details JSONB    -- деталі книжки у вигляді JSONB
);

-- Приклад вставки складної інформації про книжку
INSERT INTO books_details (title, details)
VALUES (
    '1984',
    '{"genres": ["Dystopia", "Political Fiction", "Science Fiction"],
      "isbn": "9780451524935",
      "rating": 8.9}'
);

JSONB крутий, якщо тобі треба:

  • зберігати складні чи різнорідні дані (числа, стрічки, списки, об'єкти),
  • динамічно додавати параметри без зміни структури таблиці,
  • зберігати вкладені дані (наприклад, адреси, характеристики, налаштування).

Переваги JSONB

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

Вибір між масивами і JSONB

Якщо треба зберігати тільки списки однотипних даних — юзай масиви. Наприклад:

-- Зберігання ID учасників івентів
CREATE TABLE events (
    id SERIAL PRIMARY KEY,
    participant_ids INTEGER[]
);

Якщо дані різнорідні чи складні — краще використовувати JSONB. Наприклад:

-- Зберігання інформації про клієнтів з адресами
CREATE TABLE customers (
    id SERIAL PRIMARY KEY,
    info JSONB
);

Під індексацію масиви і JSONB мають різні підходи. Для масивів частіше використовують GIN індекси, а для JSONB — GIN і BTREE, залежно від структури даних.

Продуктивність

Масиви обробляються швидше при типових задачах пошуку. JSONB трохи повільніше, але виграє у гнучкості. Якщо ти хочеш просто шукати елементи (наприклад, жанри чи ID), масиви будуть швидші:

-- Використання масивів з індексом GIN
CREATE INDEX idx_genres ON books USING GIN(genres);

-- Фільтрація книжок за жанром
SELECT * FROM books WHERE genres @> ARRAY['Science Fiction'];

Перевірка наявності даних

У JSONB більше можливостей з фільтрацією по ключах:

-- Перевірка наявності ключа "genres"
SELECT * FROM books_details WHERE details ? 'genres';

-- Перевірка наявності елемента у списку
SELECT * FROM books_details WHERE details->'genres' ?| ARRAY['Fantasy', 'Dystopia'];

Масиви дозволяють шукати значення напряму:

-- Перевірка наявності елемента у масиві
SELECT * FROM books WHERE genres @> ARRAY['Fantasy'];

Гнучкість структур

JSONB буде незамінним, якщо дані мають складні вкладені структури:

{
    "genres": ["Fantasy", "Adventure"],
    "ratings": {"goodreads": 8.5, "amazon": 4.7}
}

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

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

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