Обновления схемы базы данных

Я работаю над приложением 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, которое я писал.

В конце я написал свою собственную инфраструктуру обновления для выполнения задания (не будет работать для вас, потому что она была написана на С#). Вы можете посмотреть в текст ссылки, чтобы получить некоторые идеи.