Подтвердить что ты не робот

Как изменить дизайн базы данных в развернутом приложении?

Ситуация

Я создаю приложение С#/WPF 4 с использованием базы данных SQL Compact Edition в качестве бэкэнд с платформой Entity Framework и развертывания с помощью ClickOnce.

Я новичок в приложениях, использующих базы данных, хотя я не подозреваю, что у меня будет много проблем при проектировании и создании исходной базы данных. Тем не менее, я беспокоюсь, что в будущем мне нужно будет добавить или изменить некоторые функции, которые потребуют от меня изменить дизайн базы данных после того, как база данных уже развернута, и у пользователя есть данные в базе данных.

Вопросы

  • Возможно ли даже вывести обновленный дизайн базы данных пользователям с помощью обновления clickonce так же, как это происходит при изменении кода?

  • Если бы это было так, как повлияли бы данные пользователя?

  • Как это делается в реальных ситуациях? Каковы некоторые лучшие практики?

Я полагаю, что в худшем случае мне нужно будет создать какой-то номер версии в настройках базы данных или программы и создать некоторую процедуру, чтобы перенести текущую версию базы данных пользователя на новую.

Я ценю любое понимание моей проблемы. Большое спасибо.

4b9b3361

Ответ 1

Существуют некоторые "трюки", которые используются при разработке баз данных, чтобы разрешить изменения дизайна.

Во-первых, многие разработчики баз данных создают представления для кода вместо, а не для кодирования непосредственно в таблицах. Это позволяет изменять таблицы (разделять или объединять и т.д.), Но только требует обновления представлений. Вы можете изучить методы рефакторинга баз данных для этого.

Во-вторых, вы действительно можете добавить информацию о версии в базу данных (обычно это делается как таблица "версия" с одним полем). Обновление базы данных может осуществляться через код или через скрипты. Одна система, над которой я работал, будет автоматически проверять версию базы данных, а затем постепенно обновлять схему до версий в коде до тех пор, пока она не будет соответствовать требуемой версии для среды выполнения. Это было довольно серьезное мероприятие.

Ответ 2

Я думаю, что ваш "худший" случай на самом деле довольно хороший путь для этой ситуации. Поддерживайте версию базы данных в БД и проверяйте приложение и обновляйте БД по мере необходимости. Если вы правильно построите свой обновитель, он должен иметь возможность поддерживать пользовательские данные. В зависимости от обновления это может потребовать создания временных таблиц для хранения существующих данных и повторного заполнения новых версий таблиц. Вы можете включить новый файл SDF с новой схемой в процессе обновления и просто перенести данные. Это может быть немного проще - вы можете использовать именование файлов для дифференциации версий и запускать код обновления таким образом.

Ответ 3

К сожалению, контроль версий и управление изменениями для баз данных отчаянно, отчаянно далеки от того, что вы можете сделать с остальной частью вашего кода.

Если у вас есть внутренняя среда, есть ряд инструментов, которые помогут вам (у DBGhost, Red Gate есть новое приложение, некоторые приложения для управления развертыванием), но все они меньше полных решений imho, но они в основном достаточно хорошо.

Для клиентских решений у вас действительно нет ничего лучше, чем ваш худший случай, которого я боюсь. Просто попробуйте и разработайте с учетом гибкости - см. Ответ Dr.Herbie.

В основном это не проблема.

Ответ 4

"Интеллектуальное развертывание клиента с помощью ClickOnce" Брайана Нойеса имеет отличную главу по этой проблеме. (Глава 5) ISBN 978-0-32-119769-6

Он предлагает что-то вроде этого:

if(ApplicationDeployment.CurrentDeployment.IsFirstRun) {
    MigrateData();
}

private void MigrateData() {
    string previousDb = Path.Combine(ApplicationDeployment.CurrentDeployment.DataDirectory, @".\pre\mydb.sdf");

    if(!File.Exists(previousDb))
        return;

    string oldConnString = @"Data Source=|DataDirectory|\.pre\mydb.sdf";
    string newConnString = @"Data Source=|DataDirectory|\mydb.sdf";

    //If you are using datasets perform any migration here, with the old and new table adapters.
    //Otherwise use an .sql data migration script.
    //Store the version of the database in the database, and check that in the beginning of your update script and GOTO the correct line in the SQL script.

}

Ответ 5

Общим решением является включение номера версии в базу данных. Если у вас есть таблица с различными системными данными, бросьте туда или создайте таблицу с одной записью, чтобы удерживать номер версии БД. Затем, когда программа запускается, проверьте, меньше ли версия базы данных, чем ожидаемая. Если это так, выполните необходимые команды SQL CREATE, ALTER и т.д., Чтобы довести их до скорости. Имейте script или функцию для каждой модификации версии. Итак, если вы видите, что база данных находится сейчас в версии 6, а код ожидает версию 8, выполните обновление с 6 по 7 и обновление от 7 до 8.

Другой метод, который мы использовали в одном проекте, который я работал, заключался в том, чтобы отправить только схему, а не базу данных с кодом. Каждый раз, когда вы устанавливаете новую версию, установщик также установит последнюю копию этой новой пустой базы данных. Затем, когда программа запустила его, он сравнил схему текущей базы данных пользователя с новой схемой базы данных и определит, какие изменения базы данных были необходимы "на лету". Например, если в таблице "reference schema" Foo был столбец с именем Bar, и в текущей базе данных пользователя не было столбца Bar, мы бы сгенерировали "alter table Foo add Bar..." и выполнили его. При написании первого проекта программы для этого было достаточно много работы, как только мы это сделали, было почти нулевое обслуживание, чтобы поддерживать схему БД в актуальном состоянии. Преобразование было сделано только на лету.

Обратите внимание, что эта схема не обрабатывает изменения БД, требующие изменения значений данных, например, если вы добавляете новый столбец, который должен быть изначально заполнен путем выполнения некоторых вычислений по данным из других таблиц или некоторых таких. Но если вы можете генерировать новые данные из старых данных, это должно означать, что новые данные являются избыточными, а ваша база данных не нормализована. Я не думаю, что ситуация когда-либо возникала для нас.

Ответ 6

У меня была та же проблема с приложением в Android с базой данных SQLite, добавляющей таблицу. Я изменил имя базы данных, чтобы включить расширение версии, например: theDataBaseV1, удалил предыдущий, и приложение отлично работает.

Я просто изменил имя базы данных и имя в этой строке кода

private static final String DATABASE_NAME = "busesBogotaV2.db";

в DBManager, когда он откроется.

Кто-нибудь знает, имеют ли это тривиальное решение какие-либо непреднамеренные последствия?