Как изменить дизайн базы данных в развернутом приложении? - PullRequest
13 голосов
/ 30 сентября 2010

Ситуация

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

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

Вопросы

  1. Можно ли даже представить обновленный дизайн базы данных пользователям посредством обновления clickonce так же, как и для изменений кода?

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

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

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

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

Ответы [ 6 ]

13 голосов
/ 30 сентября 2010

При проектировании баз данных используются некоторые «хитрости», позволяющие вносить изменения в проект.

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

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

2 голосов
/ 01 октября 2010

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

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

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

2 голосов
/ 30 сентября 2010

«Развертывание Smart Client с 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.

}
2 голосов
/ 30 сентября 2010

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

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

Боюсь, что для поставляемых клиентом решений у вас нет ничего лучше, чем ваш худший случай. Просто постарайтесь проектировать с гибкостью - смотрите ответ доктора Херби.

Это не решенная проблема в принципе.

2 голосов
/ 30 сентября 2010

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

0 голосов
/ 12 марта 2014

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

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

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

в DBManager, когда он собирается открыться.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...