Миграция базы данных

Миграция базы данных — это единый, находящийся под версионным контролем файл, описывающий инкрементальное изменение схемы базы данных — создание таблицы, добавление столбца, добавление индекса, — предназначенный для применения в фиксированном порядке во всех окружениях (ноутбук разработчика, staging, продакшен), чтобы схема оставалась идентичной и воспроизводимой везде, вместо того чтобы кто-то вручную выполнял команды `ALTER TABLE`, надеясь, что все окружения останутся синхронизированными. Почему это важно для разработчиков AI/SaaS-продуктов: миграции — это механизм, с помощью которого схема безопасно эволюционирует вместе с растущим продуктом: добавление колонки `embedding vector(1536)` для новой RAG-функции, добавление колонки `tenant_id` для обеспечения изоляции мультиарендности (multi-tenancy) или добавление индекса для исправления медленного запроса — всё это миграции, зафиксированные в системе контроля версий вместе с кодом приложения, который от них зависит, так что `git checkout` любого исторического коммита соответствует схеме, которую инструмент миграций может воспроизвести в точности. Как это работает: инструменты миграций (встроенные миграции Laravel, Prisma Migrate, Alembic для Python, миграции Rails) отслеживают, какие миграции уже были выполнены (обычно в специальной таблице `migrations` в самой базе данных), и применяют только новые по порядку при запуске команды `migrate`. Миграции по возможности пишутся обратимыми (шаг `up` и шаг `down`), чтобы неудачный деплой можно было аккуратно откатить. По-настоящему сложная часть в продакшен-системах — не написание миграций, а их безопасное выполнение на живой высоконагруженной базе данных без простоя: добавление колонки обычно безопасно и быстро, но добавление ограничения `NOT NULL` к существующей большой таблице или построение индекса могут заблокировать таблицу и остановить записи на всё время выполнения, если не сделать это аккуратно (например, `CREATE INDEX CONCURRENTLY` в Postgres строит индекс без удержания блокировки на всю таблицу ценой более долгого выполнения и отсутствия транзакционности). Практический пример: команда, добавляющая векторный поиск в свой SaaS, пишет миграцию `AddEmbeddingToDocuments`, которая выполняет `ALTER TABLE documents ADD COLUMN embedding vector(1536);`, а затем `CREATE INDEX CONCURRENTLY ON documents USING hnsw (embedding vector_cosine_ops);` — параллельное (concurrent) построение индекса позволяет продакшен-базе данных продолжать обслуживать живые чтения и записи на протяжении многоминутного построения индекса на таблице с 5 миллионами строк, вместо того чтобы блокирующая, непараллельная версия останавливала записи в таблицу до завершения. Эта миграция проходит код-ревью перед слиянием именно из-за соображений безопасности продакшена — ревьюер, знакомый с трафиком команды, замечает, что наивный `CREATE INDEX` (без `CONCURRENTLY`) сделал бы таблицу documents недоступной для записи в рабочие часы — ошибка, незаметная в локальном окружении разработки с парой сотен строк и становящаяся очевидной только в продакшен-масштабе.

Похожие термины

Ещё термины: Данные и инфраструктура