Работа с БД

Тема дорожной карты · Golang

Доступ к базам данных в Go строится на многоуровневой экосистеме, начиная со стандартного пакета database/sql и расширяясь через библиотеки сообщества вплоть до полноценных ORM. На низшем уровне sql.Open возвращает пул соединений *sql.DB, а вызовы db.QueryRowContext(ctx, query, args...) с последующим row.Scan(&dest) дают прямой типобезопасный доступ к результатам запросов. Библиотека sqlx (github.com/jmoiron/sqlx) оборачивает database/sql и добавляет именованные параметры через db.NamedExecContext и автоматическое сканирование структур с помощью db.GetContext и db.SelectContext, существенно сокращая шаблонный код. Для Golang-сервисов с интенсивным использованием PostgreSQL pgx (github.com/jackc/pgx/v5) предоставляет нативный драйвер с поддержкой PostgreSQL-специфичных типов, протокола COPY для массовых вставок и кешированием подготовленных запросов, опережающим по производительности обобщённый путь через database/sql. GORM (gorm.io/gorm) и ent (entgo.io) находятся на ORM-конце спектра, предлагая кодогенерацию на основе схемы, связи, хуки и автоматические миграции ценой некоторого снижения производительности. Выбор уровня доступа к базе данных в Go зависит от сложности запросов, требований к производительности и предпочтений команды, однако все уровни выигрывают от передачи context.Context в каждый вызов для поддержки дедлайнов, отмены и трассировки с OpenTelemetry.

Как это работает

Работа с БД использует database/sql (интерфейс) + драйвер (pgx для Postgres — также экспонирует свой native-API, go-sql-driver/mysql для MySQL, mattn/go-sqlite3 для SQLite). Connection pool встроен в database/sql. ORM: GORM (популярный, full-featured, opinionated), Ent (Facebook, code-gen based), Bun (sqlx-like), sqlx (расширяет stdlib). Для миграций: golang-migrate, goose, atlas.

Когда применять

По умолчанию сырой database/sql + sqlx для явных запросов; ORM (GORM, Ent) — только если команда реально хочет. pgx напрямую (pgxpool) — для Postgres: лучшая производительность + Postgres-специфика (массивы, JSONB, COPY). Всегда параметризованные запросы ($1/? placeholders). Миграции — через тул, не через Go-код.

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

Ловушки Работа с БД: SQL-инъекция через fmt.Sprintf в запрос (всегда параметризуйте); утечка *sql.Rows (всегда defer rows.Close()); магия GORM прячет N+1 запросы; не выставлен db.SetMaxOpenConns — исчерпание соединений Postgres; context.Background() вместо контекста запроса (запросы нельзя отменить).

Связанные понятия

Полезные ресурсы