В чем разница между типами данных JSON и JSONB в PostgreSQL

Ответ

Основное различие между JSON и JSONB в PostgreSQL заключается в способе хранения данных, что напрямую влияет на производительность и возможности.

  • JSON: Хранит точную текстовую копию входных данных. Сохраняются все пробелы, порядок ключей и дубликаты ключей. При каждом запросе данные требуют повторного парсинга.

  • JSONB (B означает Binary): Хранит данные в декомпозированном бинарном формате. Пробелы удаляются, порядок ключей не сохраняется (они сортируются), а при наличии дубликатов сохраняется только последнее значение. Данные парсятся один раз при вставке.

Ключевые отличия

Характеристика JSON JSONB
Хранение Текст Бинарный формат
Скорость вставки Быстрее (нет преобразования) Медленнее (требуется парсинг)
Скорость чтения Медленнее (требуется парсинг) Значительно быстрее
Индексация Не поддерживается Поддерживаются GIN-индексы
Пробелы и порядок Сохраняются Не сохраняются

Пример использования

-- Создаем таблицу для демонстрации
CREATE TABLE products (
  id serial PRIMARY KEY,
  attributes_json JSON,
  attributes_jsonb JSONB
);

-- Вставляем данные с пробелами и разным порядком ключей
INSERT INTO products (attributes_json, attributes_jsonb)
VALUES
  ('{"price": 99.9, "name": "Gadget"  }', '{"price": 99.9, "name": "Gadget"  }');

-- Проверяем, как данные сохранились
SELECT attributes_json, attributes_jsonb FROM products;
-- attributes_json: {"price": 99.9, "name": "Gadget"  } (как есть)
-- attributes_jsonb: {"name": "Gadget", "price": 99.9} (отформатировано)

-- Создаем индекс для JSONB для ускорения запросов
CREATE INDEX idx_products_attributes ON products USING GIN (attributes_jsonb);

-- Этот запрос будет работать очень эффективно благодаря индексу
SELECT * FROM products WHERE attributes_jsonb @> '{"name": "Gadget"}';

Рекомендация: Почти всегда следует использовать JSONB, так как он обеспечивает значительно лучшую производительность запросов и поддерживает индексацию. JSON стоит выбирать только в редких случаях, когда необходимо сохранить исходное форматирование JSON-документа.