Работа с базами данных в Go: PostgreSQL и MongoDB

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему Go и базы данных — идеальная пара

Go (Golang) — это компилируемый, статически типизированный язык, созданный для высокой производительности и простоты разработки. Одним из ключевых преимуществ Go является его богатая стандартная библиотека и экосистема драйверов для работы с базами данных. В этой статье мы разберем, как подключаться и выполнять операции с двумя самыми популярными системами управления базами данных (СУБД): реляционной PostgreSQL и документоориентированной MongoDB.

Мы рассмотрим установку драйверов, написание CRUD-операций (Create, Read, Update, Delete) и лучшие практики для каждого типа БД в контексте Go-приложений.

1. Работа с PostgreSQL в Go

PostgreSQL — мощная объектно-реляционная СУБД с открытым исходным кодом. Для работы с ней в Go существует несколько драйверов, но наиболее популярными являются lib/pq и pgx. pgx — более современный и производительный, поэтому мы будем использовать его.

1.1. Установка драйвера

Установите пакет pgx через go get:

go get github.com/jackc/pgx/v5

1.2. Подключение к базе данных

Создадим файл main.go и установим соединение с PostgreSQL. Обратите внимание на использование контекста (context.Background()) — это стандартный паттерн в Go для управления временем жизни запросов.

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/jackc/pgx/v5/pgxpool"
)

func main() {
    // Строка подключения: postgres://username:password@host:port/dbname
    connString := "postgres://user:password@localhost:5432/mydb"
    
    // Создаем пул соединений (рекомендуется для production)
    pool, err := pgxpool.New(context.Background(), connString)
    if err != nil {
        log.Fatal("Не удалось создать пул соединений:", err)
    }
    defer pool.Close()
    
    // Проверяем соединение
    err = pool.Ping(context.Background())
    if err != nil {
        log.Fatal("Не удалось подключиться к БД:", err)
    }
    fmt.Println("Успешно подключено к PostgreSQL!")
}

1.3. Выполнение SQL-запросов (CRUD)

Рассмотрим основные операции на примере таблицы users.

Создание таблицы (CREATE)

// Выполнение DDL-запроса
_, err = pool.Exec(context.Background(), `
    CREATE TABLE IF NOT EXISTS users (
        id SERIAL PRIMARY KEY,
        name VARCHAR(100) NOT NULL,
        email VARCHAR(100) UNIQUE NOT NULL,
        age INT
    )
`)
if err != nil {
    log.Fatal("Ошибка создания таблицы:", err)
}

Вставка данных (INSERT)

// Вставка с возвратом ID
var userID int
err = pool.QueryRow(context.Background(),
    "INSERT INTO users (name, email, age) VALUES ($1, $2, $3) RETURNING id",
    "Алексей", "alex@example.com", 30).Scan(&userID)
if err != nil {
    log.Fatal("Ошибка вставки:", err)
}
fmt.Printf("Добавлен пользователь с ID: %d\n", userID)

Чтение данных (SELECT)

// Получение одного пользователя
type User struct {
    ID    int
    Name  string
    Email string
    Age   int
}

var user User
err = pool.QueryRow(context.Background(),
    "SELECT id, name, email, age FROM users WHERE id = $1", 1).
    Scan(&user.ID, &user.Name, &user.Email, &user.Age)
if err != nil {
    log.Fatal("Пользователь не найден:", err)
}
fmt.Printf("Найден: %+v\n", user)

Обновление и удаление (UPDATE/DELETE)

// Обновление
_, err = pool.Exec(context.Background(),
    "UPDATE users SET age = $1 WHERE id = $2", 31, 1)

// Удаление
_, err = pool.Exec(context.Background(),
    "DELETE FROM users WHERE id = $1", 1)

2. Работа с MongoDB в Go

MongoDB — ведущая NoSQL-база данных, хранящая данные в формате BSON (бинарный JSON). Официальный драйвер от MongoDB называется mongo-go-driver.

2.1. Установка драйвера

go get go.mongodb.org/mongo-driver/mongo

2.2. Подключение к MongoDB

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongodb-driver/mongo/options"
)

func main() {
    // Строка подключения
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
    
    // Создаем клиент
    client, err := mongo.NewClient(clientOptions)
    if err != nil {
        log.Fatal(err)
    }
    
    // Устанавливаем соединение (с таймаутом)
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    err = client.Connect(ctx)
    if err != nil {
        log.Fatal(err)
    }
    defer client.Disconnect(ctx)
    
    // Проверка
    err = client.Ping(ctx, nil)
    if err != nil {
        log.Fatal("Не удалось подключиться к MongoDB:", err)
    }
    fmt.Println("Успешно подключено к MongoDB!")
    
    // Получаем доступ к базе данных и коллекции
    db := client.Database("mydb")
    collection := db.Collection("users")
    _ = collection // используем далее
}

2.3. CRUD-операции с MongoDB

MongoDB использует структуры Go, аннотированные тегами BSON, для маппинга данных.

Определение модели и вставка (INSERT)

type User struct {
    ID    primitive.ObjectID `bson:"_id,omitempty"`
    Name  string             `bson:"name"`
    Email string             `bson:"email"`
    Age   int                `bson:"age"`
}

// Вставка одного документа
newUser := User{
    Name:  "Мария",
    Email: "maria@example.com",
    Age:   25,
}

result, err := collection.InsertOne(ctx, newUser)
if err != nil {
    log.Fatal(err)
}
fmt.Printf("Вставлен документ с ID: %v\n", result.InsertedID)

Чтение документов (FIND)

// Поиск одного                

Блоги

Рекомендаций по книгам