PostgreSQL + JSONB: Гибкость NoSQL без перехода на MongoDB

Как использовать JSONB в PostgreSQL для гибких данных. Примеры запросов для новичков и частые ошибки.

PostgreSQL + JSONB: Гибкость NoSQL без перехода на MongoDB

PostgreSQL и его «суперсила»: как работать с JSONB, если вы привыкли к NoSQL

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

Введение: «Почему я вообще это читаю?»

Представьте: вы только освоили основы SQL, научились создавать таблицы с пользователями и заказами, но тут возникает задача — сохранить «что-то гибкое»:

  • дополнительные характеристики товаров (например, «цвет», «размер», «материал» — но их может быть много, и они разные для каждого товара),
  • настройки пользователя (которые могут меняться и расширяться),
  • лог действий (куда нужно быстро писать и иногда что-то искать).

Обычно в таких случаях советуют NoSQL-базы вроде MongoDB, но что, если мы скажем, что ваш PostgreSQL умеет то же самое — и даже больше?

Давайте разберёмся без сложных терминов, как использовать JSONB (это «JSON, но лучше») в PostgreSQL, даже если вы раньше работали только с простыми таблицами.

1. JSONB — это как NoSQL внутри PostgreSQL

Простыми словами:

  • JSON — это способ хранить данные в формате «ключ-значение», как в MongoDB.
  • JSONB — это «сжатая» версия JSON, которая занимает меньше места и работает быстрее.
Пример:

Раньше вы создавали таблицу так:

sql
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT,
price DECIMAL
);

А теперь можно добавить поле attributes для гибких данных:

sql
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT,
price DECIMAL,
attributes JSONB -- { "color": "красный", "weight": 500, "sizes": ["S", "M"] }
);

Зачем это нужно?

Чтобы не создавать кучу дополнительных таблиц для характеристик, которые могут быть разными у каждого товара.

2. Как работать с JSONB (практические примеры)

2.1. Добавление данных

sql
-- Добавляем товар с JSON-атрибутами
INSERT INTO products (name, price, attributes)
VALUES (
'Крутая футболка',
1999.99,
'{"color": "черный", "sizes": ["M", "L"], "material": "хлопок"}'
);

2.2. Поиск по JSONB-полю

sql
-- Найти все красные товары
SELECT * FROM products
WHERE attributes->>'color' = 'красный';
-- Найти товары, у которых есть размер "L"
SELECT * FROM products
WHERE attributes->'sizes' ? 'L';

2.3. Обновление данных

sql
-- Добавить новый атрибут "discount"
UPDATE products
SET attributes = attributes || '{"discount": 10}'
WHERE id = 1;
-- Удалить атрибут "material"
UPDATE products
SET attributes = attributes - 'material'
WHERE id = 1;

3. Когда JSONB — это хорошая идея?

✅ Если данные «полуструктурированные» (например, у товаров разные характеристики).

✅ Если нужно быстро прототипировать (не надо заранее продумывать все столбцы).

✅ Если вы уже используете PostgreSQL и не хотите заводить ещё одну базу (MongoDB).

А когда JSONB не подойдёт?

❌ Если данные строго структурированы (лучше использовать обычные столбцы).

❌ Если вам нужны сложные NoSQL-запросы (как в MongoDB).

❌ Если данные огромные и нужны шардинг/репликация (PostgreSQL сложнее масштабировать).


4. Ошибки новичков (и как их избежать)


Ошибка 1: Хранить в JSONB всё подряд

Проблема:

sql
-- Плохо: зачем хранить имя и цену в JSONB, если они есть у всех товаров?
'{"name": "Футболка", "price": 1000, "color": "красный"}'

Решение:

Используйте JSONB только для необязательных/гибких данных.

Ошибка 2: Не использовать индексы

Проблема:

Поиск по JSONB без индекса работает медленно.

Решение:

sql
-- Создаём индекс для часто используемого поля
CREATE INDEX idx_products_color ON products ((attributes->>'color'));


Ошибка 3: Сложные вложенные запросы

Проблема:

sql
-- Трудно читать и поддерживать
SELECT * FROM products
WHERE (attributes->>'color' = 'красный')
AND (attributes->'sizes' ? 'L');

Решение:

Разбивайте запросы на части или используйте генерируемые столбцы.

5. Стоит ли пробовать?

Если вы раньше боялись NoSQL, но вам нужна гибкость — JSONB в PostgreSQL отличный компромисс.

Попробуйте на тестовом проекте:

  1. Создайте таблицу с JSONB-полем.
  2. Поэкспериментируйте с простыми запросами.
  3. Если понравится — используйте в реальных задачах!

Наш совет

Не стремитесь сразу сделать «идеально». Начните с малого, и постепенно разберётесь!