Расскажите о своем опыте работы с реляционными базами данных в Go. Какие пакеты и подходы вы использовали?

Ответ

Да, у меня большой опыт работы с реляционными БД, в основном с PostgreSQL и MySQL, из приложений на Go.

Мой подход основан на использовании стандартного пакета database/sql, который предоставляет универсальный интерфейс для работы с SQL-базами данных.

Ключевые концепции и практики:

  1. Пакет database/sql и драйверы: Ядро взаимодействия — это database/sql. Он не работает напрямую с БД, а использует специальные драйверы для конкретных СУБД. Например:

    • pgx или lib/pq для PostgreSQL.
    • go-sql-driver/mysql для MySQL.
  2. Пул соединений (Connection Pool): Объект sql.DB — это не одно соединение, а потокобезопасный пул соединений. Я всегда настраиваю его для оптимальной производительности:

    db.SetMaxOpenConns(25) // Макс. кол-во открытых соединений
    db.SetMaxIdleConns(25)  // Макс. кол-во соединений в простое
    db.SetConnMaxLifetime(5*time.Minute) // Макс. время жизни соединения
  3. Выполнение запросов:

    • db.Query() для запросов, возвращающих несколько строк (SELECT).
    • db.QueryRow() для запросов, возвращающих одну строку.
    • db.Exec() для запросов, не возвращающих строк (INSERT, UPDATE, DELETE).
  4. Транзакции: Для выполнения нескольких операций как единой атомарной единицы я использую транзакции, чтобы гарантировать целостность данных.

    tx, err := db.Begin()
    if err != nil { /* ... */ }
    
    _, err = tx.Exec("UPDATE ...")
    // ... другие операции
    
    if err != nil {
        tx.Rollback() // Откатываем изменения при ошибке
        return
    }
    tx.Commit() // Применяем изменения
  5. Обработка NULL: Для полей, которые могут быть NULL, я использую типы из пакета database/sql, такие как sql.NullString, sql.NullInt64, чтобы корректно обрабатывать эти значения при сканировании.

  6. ORM vs Чистый SQL: Я знаком с ORM-библиотеками, такими как GORM и sqlx. Я считаю, что ORM ускоряют разработку простых CRUD-операций, но для сложных запросов и полного контроля над производительностью я предпочитаю использовать чистый SQL с database/sql или sqlx для более удобного сканирования результатов в структуры.