Применяли ли вы типы данных JSON/JSONB в PostgreSQL?

«Применяли ли вы типы данных JSON/JSONB в PostgreSQL?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Да, применял. PostgreSQL предоставляет два типа для работы с JSON: json и jsonb.

Основные различия: Характеристика json jsonb
Хранение Текст в исходном виде (с пробелами). Бинарное разложение (оптимизированная структура).
Скорость записи Быстрее (не требует преобразования). Медленнее (из-за парсинга и преобразования).
Скорость чтения/запросов Медленнее (требует парсинг каждый раз). Значительно быстрее (работает с готовой структурой).
Поддержка индексов Только функциональные индексы. Полноценная поддержка (GIN, BTREE).
Размер на диске Меньше (исходный текст). Обычно больше (из-за накладных расходов).

Практическое использование jsonb:

  1. Создание таблицы:
    CREATE TABLE products (
        id SERIAL PRIMARY KEY,
        name TEXT NOT NULL,
        metadata JSONB -- Атрибуты продукта
    );
  2. Вставка данных:
    INSERT INTO products (name, metadata) VALUES
    ('Ноутбук', '{"color": "black", "ram_gb": 16, "ports": ["USB-C", "HDMI"]}'),
    ('Мышь', '{"color": "white", "wireless": true}');
  3. Запросы к JSON-полям:

    -- Получить значение ключа как текст (->>)
    SELECT name FROM products WHERE metadata->>'color' = 'black';
    
    -- Получить значение как JSON (->) и проверить тип
    SELECT name FROM products WHERE metadata->'wireless' = 'true';
    
    -- Проверить наличие ключа
    SELECT name FROM products WHERE metadata ? 'ports';
    
    -- Использовать JSON-операторы
    SELECT name FROM products WHERE metadata @> '{"ram_gb": 16}';
  4. Создание индекса для ускорения поиска:

    -- GIN-индекс для поддержки операторов @>, ?, & etc.
    CREATE INDEX idx_products_metadata ON products USING GIN (metadata);
    
    -- Индекс для конкретного поля
    CREATE INDEX idx_products_color ON products ((metadata->>'color'));

    Вывод: jsonb — предпочтительный выбор для большинства задач, так как он обеспечивает высокую производительность запросов за счет индексов и бинарного формата.