> Работали ли вы с JSON-полями или специфическими расширениями PostgreSQL (JavaScript, Go, PostgreSQL)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: Wildberries

Стек: JavaScript, Go, PostgreSQL

> Пример ответа

Короткий ответ

Да, я работал с JSON-полями в PostgreSQL, включая типы json и jsonb, а также с индексами GIN для эффективного поиска. Использовал их для хранения гибких схем данных, логов и конфигураций. В Go применял pq и pgx для маппинга JSON-полей в структуры, в JavaScript - через pg с автоматической сериализацией. Знаю trade-off между нормализацией и JSON, а также ограничения по производительности.

Подробное объяснение

PostgreSQL предоставляет два типа для работы с JSON: json (хранит точную копию входной строки) и jsonb (хранит в разобранном бинарном формате). jsonb предпочтительнее для большинства случаев, так как поддерживает индексацию через GIN и более быстрые операции поиска и фильтрации.

Основные возможности:

  • Операторы доступа: -> (возвращает JSON), ->> (возвращает текст), #>, #>> (path access)
  • Поиск по ключам: ?, ?|, ?& (проверка наличия ключей)
  • Containment: @> (содержит), <@ (содержится в)
  • Функции: jsonb_set, jsonb_insert, jsonb_each, jsonb_object_keys
  • Индексы: GIN для jsonb (по умолчанию поддерживает @>, ?, ?|, ?&), а также jsonb_path_ops для ускорения containment-запросов

В Go с драйвером pgx JSON-поля автоматически маппятся на []byte, string или пользовательские типы с реализацией интерфейсов sql.Scanner и driver.Valuer. В JavaScript библиотека pg автоматически парсит JSON-поля в объекты.

На практике

Основные сценарии использования JSON-полей в production:

  • Хранение метаданных с нефиксированной схемой (например, настройки пользователя, A/B тесты)
  • Логи событий и аудит с разной структурой
  • Интеграция с внешними API, где формат данных может меняться
  • Хранение древовидных структур или вложенных конфигураций

Важные ограничения:

  • JSON-поля не поддерживают foreign keys и constraints на уровне отдельных полей
  • Обновление части JSON-документа требует перезаписи всего поля (хотя jsonb_set помогает)
  • Запросы к вложенным полям медленнее, чем к обычным колонкам
  • Размер JSON-документа влияет на производительность индексов

Рекомендации:

  • Использовать jsonb вместо json всегда, когда не нужна точная сохранность пробелов и порядка ключей
  • Создавать GIN-индексы на часто запрашиваемых JSON-полях
  • Для критичных по производительности данных выносить часто используемые поля в отдельные колонки
  • Избегать хранения больших JSON-документов (более 10-20 КБ) в транзакционных таблицах

Пример кода

SQL
-- Создание таблицы с jsonb полем
CREATE TABLE user_settings (
id SERIAL PRIMARY KEY,
user_id INTEGER REFERENCES users(id),
settings JSONB NOT NULL DEFAULT '{}',
created_at TIMESTAMP DEFAULT NOW()
);
-- GIN индекс для поиска по ключам
CREATE INDEX idx_user_settings_gin ON user_settings USING GIN (settings);
-- Поиск пользователей с определённым ключом
SELECT * FROM user_settings
WHERE settings ? 'theme';
-- Поиск по вложенному значению
SELECT * FROM user_settings
WHERE settings @> '{"notifications": {"email": true}}';
-- Обновление части JSON
UPDATE user_settings
SET settings = jsonb_set(
settings,
'{notifications, email}',
'false'::jsonb
)
WHERE user_id = 123;
GO
// Go с pgx
type UserSettings struct {
ID int `db:"id"`
UserID int `db:"user_id"`
Settings map[string]interface{} `db:"settings"`
}
// Автоматическая сериализация/десериализация
var settings UserSettings
err := conn.QueryRow(ctx,
"SELECT id, user_id, settings FROM user_settings WHERE user_id = $1",
userID,
).Scan(&settings.ID, &settings.UserID, &settings.Settings)

Как отвечать на собеседовании

Начни с конкретного опыта: "Да, я активно использовал jsonb в PostgreSQL для хранения гибких схем данных". Приведи 1-2 реальных примера из проектов, где JSON-поля были оправданы, и объясни, почему выбрал именно этот подход, а не нормализацию.

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

Если спрашивают про конкретный стек, опиши, как работаешь с JSON в Go (pgx) или JavaScript (pg). Покажи знание типовых проблем: например, как избежать N+1 при работе с JSON-массивами или как организовать миграции для JSON-структур.

Что проверяет интервьюер

  • Понимание разницы между json и jsonb и когда что использовать
  • Знание операторов и функций для работы с JSON в PostgreSQL
  • Опыт с индексацией JSON-полей и её влиянием на производительность
  • Умение оценивать trade-off между JSON и нормализованными таблицами
  • Практический опыт интеграции JSON-полей с Go или JavaScript
  • Понимание ограничений JSON-полей (отсутствие constraints, сложность обновления)

Типичные ошибки

  • Использование json вместо jsonb без веской причины (потеря производительности)
  • Отсутствие GIN-индекса на часто запрашиваемых JSON-полях
  • Хранение данных, которые должны быть в отдельных таблицах (например, список email-ов в JSON-массиве вместо отдельной таблицы)
  • Попытка использовать JSON для реляционных данных с чёткой схемой
  • Игнорирование размера JSON-документа и его влияния на производительность
  • Неправильное использование операторов (например, -> вместо ->> для сравнения с текстом)
  • Отсутствие обработки ошибок при парсинге JSON в Go/JavaScript

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью