Что такое миграция базы данных?

«Что такое миграция базы данных?» — вопрос из категории Базы данных, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Миграция базы данных — это управляемое, версионное изменение схемы БД (таблицы, столбцы, индексы, ограничения), которое позволяет эволюционировать структуре данных параллельно с развитием приложения, сохраняя при этом существующие данные.

Зачем это нужно:

  • Добавление нового функционала, требующего новых таблиц или полей.
  • Рефакторинг существующей схемы (переименование, изменение типа).
  • Внесение исправлений (багфиксы) в структуру БД.
  • Обеспечение идентичности схемы БД во всех окружениях (разработка, тестирование, продакшн).

Базовый пример на SQL:

-- Миграция '001_add_user_age.sql' (накат)
ALTER TABLE users ADD COLUMN age INTEGER;

-- Соответствующий откат (rollback)
ALTER TABLE users DROP COLUMN age;

Как это работает в контексте C++ проекта: На практике для C++ приложений миграции часто управляются внешними инструментами (Flyway, Liquibase) или скриптами. Процесс выглядит так:

  1. Версионность: Каждая миграция — это файл с SQL или кодом на C++, имеющий уникальный номер или метку времени (например, 20240515_01_add_email.sql).
  2. Журнал применений: В БД создается служебная таблица (например, schema_version), которая отслеживает, какие миграции уже применены.
  3. Применение: Инструмент миграций сравнивает журнал с доступными файлами миграций и применяет недостающие в правильном порядке.
  4. Откат: Для каждой миграции часто пишется обратный SQL-скрипт, позволяющий отменить изменения при необходимости.

Пример организации в проекте:

database/
├── migrations/
│   ├── 001_initial_schema.sql
│   ├── 002_add_user_age.sql
│   └── 003_create_index_on_email.sql
└── deploy_scripts/ (запускает миграции в правильном порядке)

Ключевой принцип: Миграции должны быть идемпотентными — их повторное применение не должно ломать схему. Это часто достигается использованием конструкций вроде CREATE TABLE IF NOT EXISTS или проверкой существования столбца перед ALTER TABLE.