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. Главное — помнить про производительность и индексацию!

2
Задача
SQL SELF, 36 уровень, 0 лекция
Недоступна
Использование массивов для хранения данных
Использование массивов для хранения данных
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ