JavaRush /Курсы /SQL SELF /Работа с типом данных JSONB

Работа с типом данных JSONB

SQL SELF
16 уровень , 1 лекция
Открыта

JSON (JavaScript Object Notation) — это популярный формат данных для обмена информацией между системами. Он лёгкий, читаемый человеком и идеально подходит для представления структурированных данных, таких как объекты или массивы.

PostgreSQL поддерживает два типа данных для работы с JSON:

  • JSON: хранит данные в виде строки. Это чисто текстовое представление JSON, без внутренней оптимизации.
  • JSONB: бинарное представление JSON. Оно более эффективно для чтения, фильтрации и обработки, так как PostgreSQL заранее парсит JSON и оптимизирует его хранение.

Почему чаще выбирают JSONB? Потому что:

  • Он быстрее для запросов благодаря бинарному хранению.
  • Умеет индексироваться, что делает его идеальным для больших наборов данных.
  • Сохраняет ключи упорядоченными и убирает дубли, что упрощает обработку.

Пример JSON-структуры:

{
  "name": "Alice",
  "age": 25,
  "skills": ["SQL", "PostgreSQL", "JSONB"]
}

Почему JSONB полезен?

Хранение полуструктурированных данных. В реальном мире данные часто приходят в виде сложных объектов (например, метаданные, настройки, профили пользователей). JSONB позволяет хранить их, избегая создания сотен таблиц и связей.

Моделирование данных, которые изменяются. Когда структура объекта часто меняется (например, добавляются или удаляются поля), JSONB позволяет гибко хранить такие данные.

Работа с API. Многие веб-приложения отправляют данные в формате JSON. Вместо преобразования запросов можно хранить их "как есть" и работать с ними напрямую.

Создание таблицы с JSONB

Давайте начнем с практики! Представьте, что мы создаём базу данных для хранения профилей пользователей.

Столбец profile будет хранить всю дополнительную информацию (например, возраст, интересы, контакты) в формате JSON. Это удобно, если структура хранения данных варьируется от пользователя к пользователю.

id name - VARCHAR(100) profile - JSONB
1 Alice {"age": 25, "skills": ["SQL", "PostgreSQL", "JSONB"], "location": "New York"}
2 Bob {"age": 30, "interests": ["hiking", "photography"], "location": "Denver"}
3 Charlie {"email": "charlie@example.com", "verified": true}
4 Diana {"age": 22, "skills": ["Python"], "bio": "Data enthusiast", "location": "Berlin"}
5 Eve {"age": 28, "skills": [], "preferences": {"theme": "dark", "notifications": false}}

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

Извлечение данных из JSONB

Теперь, когда у нас есть данные, давайте узнаем, как их извлекать. PostgreSQL предоставляет множество операторов для работы с JSONB.

Доступ к значению поля

Используем оператор -> для получения значения поля:

-- Выводим возраст пользователя
SELECT profile->'age' AS age FROM users;

Преобразование значения в текст

Оператор ->> позволяет извлечь значение в виде строки:

-- Выводим место жительства пользователя
SELECT profile->>'location' AS location FROM users;

Фильтрация данных с JSONB

Мощь JSONB раскрывается в запросах с фильтрацией. Мы можем использовать стандартные SQL-операторы для работы с JSON.

Пример фильтрации по ключу:

-- Найти пользователей, у которых указано место жительства "New York"
SELECT * FROM users
WHERE profile->>'location' = 'New York';

Поиск в массиве

JSON поддерживает массивы, и PostgreSQL умеет искать в них значения:

-- Найти пользователей, которые владеют SQL
SELECT * FROM users
WHERE 'SQL' = ANY(jsonb_array_elements_text(profile->'skills'));

Функция jsonb_array_elements_text превращает элементы массива в строки, чтобы их можно было сравнить.

Есть и более короткий вариант с использованием оператора @>:

-- Найти пользователей, которые владеют SQL
SELECT * FROM users
WHERE profile->'skills' @> '["SQL"]';

Подробнее об функциях и способах работы с JSON мы поговорим позже, когда придет время :P

Краткое резюме: когда использовать JSONB

JSONB отлично подходит для:

  • Хранения сложных структурированных данных.
  • Обработки данных из внешних API.
  • Ситуаций, когда структура объекта меняется.

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

2
Задача
SQL SELF, 16 уровень, 1 лекция
Недоступна
Извлечение данных из JSONB
Извлечение данных из JSONB
2
Задача
SQL SELF, 16 уровень, 1 лекция
Недоступна
Фильтрация данных с использованием JSONB
Фильтрация данных с использованием JSONB
Комментарии (11)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Анатолий Уровень 52
1 февраля 2026
❤️
Slevin Уровень 59
9 сентября 2025
Задания дурацкие, т.к. в данных для заданий таблицах нет записей однозначно удовлетворяющих условиям, что может вводить в заблуждение относительно правильности запроса.
Александр Уровень 112
16 декабря 2025
Это же сколько можно ныть... И как должно быть скучно, чтобы оставлять дурацкие комментарии почти к каждой лекции
Denis Murashko Уровень 49
3 сентября 2025
вторая задача не работает, валидатор выводит неверное решение т.к. у боба нету скила sql и вообще нету записи подходящей под условие
17 июля 2025
Если у вас не проходят тесты на 1е задание, но решение соответствует правильному, просто внесите изменения в init.sql

INSERT INTO users (name, profile) VALUES
('Alice', '{"age": 25, "location": "Moscow", "skills": ["SQL", "PostgreSQL", "JSONB"]}'),
('Bob', '{"age": 30, "interests": ["hiking", "photography"]}'),
('Charlie', '{"email": "charlie@example.com", "verified": true}'),
('Diana', '{"age": 22, "skills": ["Python"], "bio": "Data enthusiast"}'),
('Eve', '{"age": 28, "skills": [], "preferences": {"theme": "dark"}}');
Fanil Magdiew Уровень 31 Expert
4 августа 2025
не могу понять почему с вашими изменениями валидатор сработал
Alexandr Уровень 61
12 июля 2025
Первая задача - некорректно работает валидатор: не проходит даже правильный ответ от разработчиков. Вторая задача - необходимо использовать явное приведение типов: "::jsonb" и "::int".
28 июня 2025
Предложенный код не работает Поиск в массиве JSON поддерживает массивы, и PostgreSQL умеет искать в них значения:

-- Найти пользователей, которые владеют SQL
SELECT * FROM users
WHERE 'SQL' = ANY(jsonb_array_elements_text(profile->'skills'));
-- ERROR: set-returning functions are not allowed in WHERE
Необходимо использовать такую конструкцию, но это уже относиться к массивам

SELECT * FROM users
WHERE profile -> 'skills' @> '["SQL"]';
27 июня 2025
В первой задаче нужно каждое поле вынести в отдельную строку )))))
thomY Уровень 1
30 июня 2025
можно подробнее? пробовал через union, но не прошло
8 июля 2025
даже Правильный ответ не проходит валидацию 😤