Миграция базы данных — это контролируемое изменение структуры (схемы) базы данных с отслеживанием версий. Миграции позволяют синхронизировать схему БД с кодом приложения, откатывать изменения и работать в команде с единой версией структуры данных.
Ключевые аспекты
Версионирование — каждая миграция имеет уникальный номер/timestamp, применяется последовательно
Up и Down — миграция содержит код применения (up) и отката (down)
Таблица миграций — БД хранит список применённых миграций для отслеживания состояния
Идемпотентность — миграция должна безопасно применяться повторно (или проверять, была ли применена)
Автоматизация — миграции запускаются автоматически при деплое
Что можно делать в миграциях
Создавать/удалять таблицы и колонки
Добавлять/удалять индексы и constraints
Менять типы данных колонок
Переносить данные между таблицами
Заполнять начальные данные (seed)
Частые ошибки на собеседованиях
Путают миграции с backup/restore — миграции меняют структуру, backup сохраняет данные
Забывают про down миграции — без них невозможен откат
Редактируют уже применённые миграции — это нарушает консистентность; нужна новая миграция
Не тестируют миграции локально — миграция может сломать production
Делают деструктивные изменения без подготовки — удаление колонки с данными без backup
Введение и проблематика
Зачем нужны миграции?
Представьте ситуацию: у вас работает приложение в production. Нужно добавить новое поле в таблицу пользователей. Как это сделать безопасно?
Без системы миграций:
Ручное выполнение SQL на сервере
Нет истории изменений
Невозможно откатить
Разработчики не синхронизированы
С миграциями:
Автоматическое применение изменений
Полная история в git
Возможность отката
Все разработчики с одинаковой схемой
Миграции — это "git для схемы базы данных". Как git отслеживает изменения кода, миграции отслеживают изменения структуры БД.
Базовая теория
Что такое миграция?
Миграция — это файл (или набор файлов), описывающий изменения структуры базы данных. Каждая миграция содержит:
Уникальный идентификатор — timestamp или порядковый номер
Up операция — код для применения изменений
Down операция — код для отката изменений
Как работают миграции
graphLR A[Код миграции]--> B[Инструмент миграций] B --> C{Проверка таблицы миграций} C -->|Не применена| D[Выполнить UP] C -->|Уже применена| E[Пропустить] D --> F[Записать в таблицу миграций]
Таблица миграций
Инструмент миграций создаёт служебную таблицу для отслеживания:
sql
-- Пример таблицы миграций (Knex.js)CREATETABLEknex_migrations ( id SERIALPRIMARY KEY,nameVARCHAR(255) NOT NULL, -- имя файла миграции batch INTEGERNOT NULL, -- номер группы миграций migration_time TIMESTAMP-- когда применена);
Разработчик создаёт файл миграции с описанием изменений.
Локальное тестирование
Миграция применяется на локальной базе данных для проверки.
Code review
Миграция проверяется в pull request вместе с кодом приложения.
Применение на staging
Миграция тестируется на staging окружении.
Применение в production
Миграция автоматически применяется при деплое.
Команды миграций
Knex.js
bash
# Создать новую миграциюnpxknexmigrate:makecreate_orders# Применить все новые миграцииnpxknexmigrate:latest# Откатить последнюю группу миграцийnpxknexmigrate:rollback# Откатить все миграцииnpxknexmigrate:rollback--all# Показать статус миграцийnpxknexmigrate:status
Prisma
bash
# Создать миграцию из изменений в schema.prismanpxprismamigratedev--nameadd_orders# Применить миграции в productionnpxprismamigratedeploy# Сбросить БД и применить все миграцииnpxprismamigratereset# Показать статусnpxprismamigratestatus
Пограничные кейсы
⚠️
Никогда не редактируйте уже применённые миграции! Если миграция применена в production, создайте новую миграцию для исправления. Редактирование сломает консистентность между окружениями.
🚫
Деструктивные операции требуют осторожности:
DROP COLUMN удаляет данные безвозвратно
Изменение типа колонки может потерять данные
Всегда делайте backup перед деструктивными миграциями
Безопасное удаление колонки
Перестать использовать колонку в коде
Код больше не читает и не пишет в колонку.
Задеплоить изменения кода
Убедиться, что колонка не используется.
Создать миграцию удаления
Только после предыдущих шагов.
Сделать backup
На случай, если данные понадобятся.
Применить миграцию
Удалить колонку из базы данных.
Плюсы и минусы
Плюсы
Минусы
История изменений в git
Требует дисциплины в команде
Возможность отката
Сложные миграции данных
Синхронизация команды
Конфликты при параллельной работе
Автоматизация деплоя
Блокировки при ALTER TABLE
Воспроизводимость
Необходимость поддержки down
Вопросы интервьюера
Q: Что делать, если миграция упала в production?
Откатить миграцию (down), исправить проблему, создать новую версию миграции. Никогда не редактировать упавшую миграцию — она уже может быть частично применена.
Q: Как тестировать миграции?
Применять на локальной копии production базы. Проверять, что up работает, down работает, и up после down даёт тот же результат.
Q: Можно ли запускать миграции параллельно?
Нет, миграции должны выполняться последовательно. Инструменты миграций используют блокировки для предотвращения параллельного выполнения.
Q: Как избежать downtime при миграции?
Использовать online schema change инструменты, делать изменения в несколько этапов (expand-contract pattern), добавлять колонки как nullable.