Миграция базы данных в Java
Время от времени в практике Java-разработчика появляется необходимость изменить схему базы данных. Например, надо добавить колонку в таблицу или наоборот, удалить. Кажется, что это очень простая задача и говорить тут особенно не о чем, однако в этом деле есть свои тонкие моменты.
Данные – это великая ценность, и поэтому требуют особой осторожности в обращении.
Рассмотрим такую ситуацию
В таблице есть колонка – FIO, в ней хранятся Фамилия, Имя и Отчество – все одной строкой.
В какой-то момент принято решение эту колонку разделить на три независимых: FirstName, SecondName, LastName.
Допустим, java-код поменяли и теперь надо изменить таблицу базы данных.
Хочется написать такой скрипт: - создать три новые колонки; - выполнить Update, который перенесет данные из старой колонки FIO в новые три; - сделать новые колонки NOT NULL; - удалить старую колонку FIO.
Одним скриптом мы выполняем поставленную задачу.
Однако есть нюансы: нам обязательно надо одновременно «деплоить» и измененный java-код и этот sql-скрипт модификации таблицы. Это изменение ломает обратную совместимость между версиями. Т. е. после применения этого скрипта мы уже не сможем использовать предыдущую версию нашей java-программы. А это может потребоваться, если в новой версии найдется критический баг и придется срочно «откатываться» на предыдущую версию.
Есть и другой вариант. Можно выполнить миграцию в два этапа.
На первом этапе выполняем скрипт, который: - создаст три новые колонки; - выполнит Update, который перенесет данные из старой колонки FIO в новые три.
При этом так меняем java-код, чтобы он работал и со старой колонкой, и с новыми, т. е. чтобы делал синхронные изменения.
На втором этапе другой скрипт выполняет: - делает новые колонки NOT NULL; - удаляет старую колонку FIO.
Из java-кода уберем функционал для работы с полем FIO.
Какие выгоды мы извлечем при таком подходе?
Во-первых, сможем первый скрипт выполнить до «деплоя» Java-кода – часто это очень удобно, т. к. изменение схемы базы данных довольно сложная в организационном плане операция.
Во-вторых, у нас появляется возможность «откатиться» на предыдущую версию.
У этого подхода может быть вариация – «задеплоить» новый java-код, убедиться, что все в порядке и получилось то, что надо и только после этого удалить старую колонку из FIO.
Миграция данных в несколько этапов кажется более трудоемкой, это так. Однако в обмен за бОльшую трудоемкость мы получаем бОльшую гибкость в работе и надежность, а это того стоит.