На работе мы разработали небольшой скрипт для управления версиями нашей базы данных. Каждое изменение в любой таблице или наборе данных получает свой собственный файл SQL.
Файлы нумеруются последовательно. Мы отслеживаем, какие файлы обновлений были запущены, сохраняя эту информацию в базе данных. Сценарий вставляет строку с именем файла, когда файл собирается быть выполненным, и обновляет строку с отметкой времени завершения, когда выполнение завершается. Это обернуто внутри транзакции. (Стоит помнить, что команды DDL в MySQL не могут выполняться внутри транзакции. Любая попытка выполнить DDL в транзакции вызывает неявную фиксацию.)
Поскольку файлы SQL являются частью нашего репозитория исходного кода, мы можем сделать запуск сценария обновления частью обычного процесса развертывания. Это упрощает синхронизацию базы данных и кода как пирог. Честно говоря, самое сложное - убедиться, что другой разработчик не получил следующий номер в ожидающем коммите.
Мы объединяем эту систему обновлений с (необязательным) ночным стиранием нашей базы данных разработчиков, заменяя ее содержимым с резервной копией системы прошлой ночью. После восстановления резервной копии обновление запускается, и в процессе запускаются все ожидающие обновления файлы.
Восстановление происходит таким образом, что перезаписываются только таблицы, которые были в действующей базе данных. Поэтому любое обновление, которое добавляет таблицу, также должно отвечать только за ее добавление, если оно не существует. DROP TABLE IF EXISTS
удобно. К сожалению, не все базы данных поддерживают это, поэтому система обновлений также позволяет выполнять сценарии, написанные на нашем языке по выбору, а не только на SQL.
Все это примерно в 150 строках кода. Это так же просто, как чтение каталога, сравнение содержимого с таблицей и выполнение всего, что еще не было выполнено, в определенном порядке.