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

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

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

Начать курс

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

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

1. Подготовка среды и установка драйверов

Перед началом работы убедитесь, что у вас установлен Go версии 1.19 или выше. Для работы с базами данных нам понадобятся два основных пакета:

  • database/sql — стандартный пакет Go для работы с SQL-базами (общий интерфейс);
  • lib/pq — драйвер для PostgreSQL;
  • go.mongodb.org/mongo-driver — официальный драйвер MongoDB.

Установка драйверов через go get:

go get github.com/lib/pq
go get go.mongodb.org/mongo-driver/mongo

Создайте новый модуль вашего проекта:

mkdir go-db-example
cd go-db-example
go mod init go-db-example

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

PostgreSQL — это мощная объектно-реляционная СУБД. В Go работа с ней строится через интерфейс database/sql.

2.1 Подключение к базе

Создадим файл main.go и напишем подключение к локальной базе данных Postgres:

package main

import (
    "database/sql"
    "fmt"
    "log"

    _ "github.com/lib/pq"
)

func main() {
    // Строка подключения: user password dbname sslmode
    connStr := "user=postgres password=mysecretpassword dbname=testdb sslmode=disable"
    db, err := sql.Open("postgres", connStr)
    if err != nil {
        log.Fatal("Ошибка подключения:", err)
    }
    defer db.Close()

    // Проверяем соединение
    err = db.Ping()
    if err != nil {
        log.Fatal("Не удалось подключиться к БД:", err)
    }
    fmt.Println("Успешно подключено к PostgreSQL!")
}

2.2 Создание таблицы и вставка данных

После подключения создадим таблицу users и вставим несколько записей:

// Создание таблицы
createTable := `
CREATE TABLE IF NOT EXISTS users (
    id SERIAL PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    age INT
);`

_, err = db.Exec(createTable)
if err != nil {
    log.Fatal("Ошибка создания таблицы:", err)
}

// Вставка данных
insert := `INSERT INTO users (name, email, age) VALUES ($1, $2, $3)`
_, err = db.Exec(insert, "Анна Петрова", "anna@example.com", 28)
if err != nil {
    log.Fatal("Ошибка вставки:", err)
}
fmt.Println("Данные добавлены")

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

Используем QueryRow для одной записи и Query для множества:

// Получение одной записи
var id int
var name, email string
var age sql.NullInt64

row := db.QueryRow("SELECT id, name, email, age FROM users WHERE email = $1", "anna@example.com")
err = row.Scan(&id, &name, &email, &age)
if err != nil {
    log.Fatal("Ошибка сканирования:", err)
}
fmt.Printf("ID: %d, Имя: %s, Email: %s, Возраст: %v\n", id, name, email, age)

// Получение всех записей
rows, err := db.Query("SELECT id, name, email FROM users ORDER BY id")
if err != nil {
    log.Fatal("Ошибка запроса:", err)
}
defer rows.Close()

for rows.Next() {
    err := rows.Scan(&id, &name, &email)
    if err != nil {
        log.Fatal("Ошибка чтения строки:", err)
    }
    fmt.Printf("User: %d | %s | %s\n", id, name, email)
}

Важно: Всегда обрабатывайте sql.NullInt64 для nullable-полей, чтобы избежать паники при NULL-значениях.

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

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

3.1 Подключение к MongoDB

package main

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

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

func main() {
    // Контекст с таймаутом
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()

    // Подключение к локальному инстансу MongoDB
    clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
    client, err := mongo.Connect(ctx, clientOptions)
    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!")

    // Выбираем базу данных и коллекцию
    collection := client.Database("testdb").Collection("users")
    _ = collection // используем далее
}

3.2 CRUD-операции с MongoDB

Определим структуру пользователя и выполним базовые операции:

import (
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
)

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

// --- CREATE ---
user := User{Name: "Иван Иванов", Email: "ivan@example.com", Age: 30}
result, err := collection.InsertOne(ctx, user)
if err != nil {
    log.Fatal("Ошибка вставки:", err)
}
fmt.Println("Вставлен ID:", result.InsertedID)

// --- READ (FindOne) ---
var foundUser User
err = collection.FindOne(ctx, bson.M{"email": "ivan@example.com"}).Decode(&foundUser)
if err != nil {
    log.Fatal("Пользователь                

Блоги

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