Версионная миграция данных нужна во время разработки, чтобы не столкнуться с проблемой рассинхронизации версий БД и приложения при поставке новой версии приложения в продакшн. Обновление версии приложения требует корректной версионной миграции БД. Корректность заключается в том, чтобы
в процессе версионной миграции все SQL-запросы выполнялись лишь единожды и строго в определенной последовательности, так как одни изменения могут зависеть от других.
Пример ошибки при повторном запросе. Если повторно выполнить запрос замены паролей на их MD5-суммы, то данные можно будет восстановить только из бэкапа.
Пример ошибки при нарушении последовательности запросов. Если в одной из таблиц есть необнуляемое строковое поле (not nullable) без данных (пустая строка), то вы можете решить, что семантически неправильно хранить пустые строки. Правильно было бы хранить NULL'ы. Последовательность действий здесь должна быть такой:
- Изменить тип поля на nullable.
- Заменить в этой таблице на продакшн БД пустые строки на NULL.
- Изменить код приложения так, чтобы при получении из БД данных, хранящихся в этом поле, код адекватно реагировал на NULL'ы. Теперь в это поле вместо пустых строк надо записывать NULL'ы.
Если до новой версии будет обновлено только приложение (п.3) без БД (п-п 1-2), то в какой-то момент произойдет вставка NULL в поле not nullable, что будет являться ошибкой.
Существует несколько различных подходов к организации версионной миграции баз данных: метод инкрементных изменений, метод идемпотентных изменений, метод уподобления структуры БД исходному коду и другие. Также имеется множество готовых инструментов для версионной миграции БД: Migrator.NET, ECM7.Migrator, Active Record Migrations, SQL Source Control, DotNetMigrations, Fluent Migrator, DbDeploy.NET, Tarantino, Mygrate, DBUpdater, Wizardby и другие. Однако какой бы подход не применялся, в процессе создания и хранения версионных миграций желательно придерживаться следующих принципов:
- чтобы любую версию БД можно было обновить до любой версии;
- чтобы набор SQL-запросов, которые позволяют реализовать миграцию между любыми двумя версиями, можно было получить максимально быстро и просто;
- чтобы всегда можно было создать БД с нуля со структурой самой последней версии (полезно как при развертывании нового продакшн-сервера, так и в процессе разработки и тестирования приложения);
- чтобы при слиянии разных веток после работы над ними ручное редактирование файлов БД было сведено к минимуму;
- чтобы откатить БД на более раннюю версию было так же просто, как и обновить на более новую.
Примечание: раздел о версионной миграции даных подготовлен по материалом этой экспертной статьи.