Обновления схемы базы данных
Я работаю над приложением AIR, использующим локальную базу данных SQLite, и задавался вопросом, как я могу управлять обновлениями схемы базы данных при распространении новых версий приложения. Также рассматривайте обновления, которые пропускают некоторые версии. Например. вместо перехода от 1.0 к 1.1, от 1.0 до 1.5.
Какую технику вы порекомендуете?
Ответы
Ответ 1
Мы script каждый DDL меняем на БД, и когда мы делаем "выпуск", мы объединяем их в одно "обновление" script вместе с любыми хранимыми процедурами, которые изменились "с последнего времени"
У нас есть таблица, в которой хранится номер версии последнего исправления, поэтому инструменты обновления могут применять любые новые патчи.
Каждая хранимая процедура находится в отдельном файле. Каждый из них начинается с оператора "insert" в таблицу протоколирования, в которой хранятся имя SProc, Version и "now". (На самом деле SProc выполняется для хранения этого, это не сырая инструкция вставки).
Иногда во время развертывания мы вручную меняем параметры SProc, или свертывания и заканчиваем работу с DEV, а сравнение баз данных TEST и PRODUCTION на клиенте клиента позволяет нам проверить, что все в одной версии.
У нас также есть базовая база данных "release", к которой мы применяем обновления, и мы используем восстановленную резервную копию для новых установок (экономит время запуска скриптов, которые, очевидно, увеличиваются с течением времени). Мы обновляем это как и когда, потому что, очевидно, если он немного устарел, могут применяться более поздние скрипты патча.
В нашей базе данных Release также содержатся дезинфицированные исходные данные (которые удаляются, а иногда и принимаются и изменяются до того, как новая установка идет в прямом эфире, поэтому это не входит в какие-либо сценарии обновления)
SQL Server имеет кнопку панели инструментов для script изменения - поэтому вы можете использовать инструменты GUI для внесения всех изменений, но вместо сохранения вместо них генерируйте script. (на самом деле есть флажок всегда генерировать script, поэтому, если вы забыли и просто нажмите SAVE, он по-прежнему дает вам script, который используется после факта, который можно сохранить как файл исправления)
Ответ 2
В случае SQLite вы можете использовать прагму user_version для отслеживания версии базы данных. Чтобы получить версию:
PRAGMA user_version
Чтобы установить версию:
PRAGMA user_version = 5
Затем я сохраняю каждую группу обновлений в файле SQL (встроенном в приложение) и запускаю обновления, необходимые для получения самой последней версии:
Select Case currentUserVersion
Case 1
// Upgrade to version 2
Case 2
// Upgrade to version 3
Case etc...
End Select
Это позволяет приложению обновляться самой последней версией независимо от текущей версии БД.
Ответ 3
IMO проще всего обработать обновление, например. 1.0 до 1.5 в виде последовательности обновлений от 1.0 до 1.1, 1.1 до 1.2 и т.д. Для каждого изменения версии сохраните преобразование script/фрагмент кода.
Затем сохраните таблицу с полем версии в базе данных и скопируйте в приложение требуемую версию. При запуске, если поле версии не соответствует скомпилированной версии, запустите все необходимые сценарии конвертации один за другим.
Сценарии конверсии должны идеально начинать транзакцию и записывать новую версию в базу данных в качестве последнего оператора перед совершением транзакции.
Ответ 4
То, что я рассматриваю, заключается в добавлении таблицы SchemaVersion в базу данных, которая содержит запись для каждой версии, которая существует. Последней версией таблицы SchemaVersion является текущий уровень базы данных.
Я собираюсь создать (SQL) скрипты, которые выполняют начальную настройку 1.0, а затем обновление от 1.0 до 1.1, 1.1 до 1.2 и т.д.
Даже новая установка, например, 1.2 будет проходить через все эти сценарии. Это может показаться немного медленным, но выполняется только один раз и в (почти) пустой базе данных.
Большим преимуществом этого является то, что новая версия будет иметь ту же схему базы данных, что и обновленная установка.
Как я уже сказал: я рассматриваю это. Я, вероятно, начну выполнять это завтра. Если вам интересно, я могу поделиться своим опытом. Я буду реализовывать это для приложения С#, которое использует LINQ-to-entity с SQL Server и MySQL как СУБД.
Мне интересно услышать любые другие предложения и идеи, и если кто-нибудь может указать мне открытую библиотеку .Net или классы, которые реализуют что-то вроде этого, это было бы здорово.
EDIT:
В ответе на другой вопрос здесь, на SO я нашел ссылку на Migrator.Net. Я начал использовать его сегодня, и похоже, что это именно то, что я искал.
Ответ 5
У меня была такая же проблема в приложении .net, которое я писал.
В конце я написал свою собственную инфраструктуру обновления для выполнения задания (не будет работать для вас, потому что она была написана на С#). Вы можете посмотреть в текст ссылки, чтобы получить некоторые идеи.