Миграция БД

Бывает что при обновлении версии работающего приложения тратится иногда по нескольку часов на приведение структуры БД к новому виду. Ну т.е. добавление колонок, переименовывание, смена связей и пр. При этом DBA сидит и по diff двух инициализационных sql (для текущего приложения и для нового) пытается понять что менялось и как нужно прописать все эти ALTER TABLE ..., или того хуже UPDATE по хитрым условиям. Когда то, по неопытности, и мы так делали, при этом приложение клиента ждало (т.е. не работало) иногда по нескольку часов. Слава богу у них в это время была ночь и заказчик сладко спал, иначе бы много чего могли бы наслушаться.

Позже, на другом проекте, был подход написания sql патчей, в котором разработчик прописывал все свои изменения структуры БД. К тому же надо было не порушить текущие данные, в результате писались апдейты на несколько страниц (ну это нормально). Правда в первый раз мы все равно косячнули, т.к. пытались писать патч в одном файле, на весь релиз. Во-первых не совсем удобно всем лезть в один файл (и постоянно мержить), во-вторых он быстро разрастался, ну и в третьих все равно не всегда работал (и фиг ведь найдешь кто виноват) 🙁 Последнее правда поправимо, надо лишь договориться с тем как пополнять скрипт.

Далее все выросло до следующего варианта: при выполнении задачи пишется ###.название.sql, где название"" лишь для визуальной идентификации, а вот эти ### для очередности выполнения скриптов. Для небольшого проекта это простой счетчик. т.е. файлы 001.extend_user.sql, 002.optimize_prod_view.sql и т.д. Да, и если номера совпали у двух разработчиков, то чаще всего проблемы не возникнет, если они не меняли одну область БД. Когда же проект побольше, то можно нумеровать в виде yyMMdd.title.sql или даже yyMMdd.HHmm.title.sql. Хотя в любом случае нужно разруливать на уровень выше, при планировании задач связанных с БД.

А запустить полученные скрипты может как ДБА, так и shell скрипт, который написать совсем не проблема. Для упрощения можно еще завести табличку version содержащую актуальный номер (тот самый, с которого начинаются наши файлы sql) и тогда процедура обновления версии вовсе станет автоматической.

Все это не претендует на новизну, лишь совет при планировании начальной архитектуры, почему то часто об этом забывают. Ну а вообще в RoR это сразу встроено. К GRails есть отдельный плагин. Да и отдельно для Java есть библиотека облегчающая такой процесс. Правда она добавляет свой оверхед по написанию этих апдейтов, так что тут дело вкуса.

PS: pgAdmin (менеджер для PostgreSQL) в данном случае очень удобен, по нажатию на любой объект, будь то таблица, колонка, индекс, вьюха или что угодно, он сбоку покажет SQL для удаления и создания этого объекта. В результате все эти alter table писать не приходится, достаточно скопировать.