Миграция базы данных Oracle с приложением C #: как управлять миграцией базы данных? - PullRequest
3 голосов
/ 31 января 2009

У меня есть приложение C #, которое работает с базой данных Oracle и уже отправлено. Теперь пришло время выпустить новый релиз. Объектная модель C # была пересмотрена и оказала влияние на структуру таблицы.

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

Чтобы противостоять этой проблеме, я собрал SQL-сценарии, которые изменяют ранее выпущенную структуру базы данных на новую структуру базы данных. В ходе этого данные также переносятся. Сценарии SQL передаются в хранилище, такое как исходный код C #. Исправление базы данных регулярно тестируется с помощью CruiseControl.NET. Тесты NUnit запускаются для исправленной базы данных, чтобы выявить несоответствия между таблицами базы данных и объектной моделью C #.

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

На прошлой неделе я споткнулся о LiquiBase , и я спросил себя - и теперь в SO:

Какие инструменты или методы могут помочь выполнить миграцию базы данных с меньшими рисками и большей уверенностью? Есть ли хорошие книги или интернет-ресурсы?

Меня особенно интересуют конкретные решения для C # и Oracle, которые могут вписаться в описанную выше процедуру разработки.

Ответы [ 4 ]

5 голосов
/ 01 февраля 2009

Сценарии обновления базы данных должны быть частью процесса разработки. Вот один из способов отслеживать обновления схемы базы данных:

  • создать таблицу VERSION в базе данных, которая содержит одну запись с номером версии
  • каждый раз, когда вы вносите изменения в схему базы данных вашего приложения, вы должны:
    • создание сценария SQL для создания, изменения или удаления объектов базы данных
    • создание сценария SQL для управления изменениями данных, которые должны выполняться с новой схемой данных (например, вставка значений по умолчанию в новые поля, вставка записей по умолчанию в новые таблицы, создание сценария для разделения или объединения таблиц, ...)
    • увеличить номер версии базы данных
      • Для каждого изменения я обычно создаю один скрипт с именем DbVerXXXX.SQL, который содержит все необходимые обновления (XXXX - номер версии). Кроме того, я делаю изменения небольшими шагами - меняйте схему БД только для следующего изменения, которое вы внесете в свое приложение. Не создавайте обновление базы данных, которое займет недели или месяцы работы для обновления вашего приложения.
  • создать скрипт, который обновит базу данных вашего пользователя до новой версии:
    • должен проверить текущую версию базы данных, а затем выполнить сценарии обновления базы данных, которые преобразуют схему в требуемый уровень
    • изменить номер версии в таблице VERSION

Этот процесс позволяет вам:

  • поставить все изменения схемы базы данных под контроль исходного кода, чтобы у вас была полная история изменений
  • попробуйте протестировать ваши скрипты обновления на тестовых базах данных, прежде чем отправлять их клиенту
  • автоматическое обновление пользовательских баз данных с уверенностью
0 голосов
/ 13 февраля 2013

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

Тем не менее, его процесс немного слишком ручной, и вам могут быть интересны более автоматизированные инструменты для этой цели.

Выезд:

Вы также можете рассмотреть идеи этих инструментов и разработать свои собственные.

0 голосов
/ 31 января 2009

Чтобы быть уверенным, что вы не потеряете данные при изменении базы данных, вы можете создать сценарии для подтверждения новой структуры, а старая содержит те же логические данные. Например, скажем, версия 1 базы данных выглядит следующим образом (псевдокод)

CREATE TABLE Customer
CustomerID INT, 
FirstName string,
Surname string,
AddressLine1 string,
AddressLine2 string,
AddressLine3 string,
AddressLine4 string

В версии 2 вы хотите, чтобы клиенты могли иметь более одного адреса, поэтому вы перемещаете поля адреса в новую таблицу:

CREATE TABLE Address
AddressID INT,
CustomerID INT,
AddressLine1 string,
AddressLine2 string,
AddressLine3 string,
AddressLine4 string

Вы перемещаете адреса из таблицы Customer в новую таблицу адресов следующим образом:

INSERT Address
CustomerID ,
AddressLine1 ,
AddressLine2 ,
AddressLine3 ,
AddressLine4 

SELECT
*
FROM Customer

Затем вы удаляете избыточные поля адреса из Customer:

ALTER TABLE Customer
DROP COLUMNS 
AddressLine1 ,
AddressLine2 ,
AddressLine3 ,
AddressLine4 

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

Мы можем подтвердить перемещение полей адреса, запустив

Если при этом возвращаются какие-либо записи, обновление завершилось неудачно, поскольку некоторые клиенты не получили свой адрес:

SELECT 
 *
FROM

  OldCustomerTable  OCT LEFT JOIN Address A
  ON OCT.CustomerID = A.CustomerID
WHERE 
  A.CustomerID IS NULL

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

SELECT
  *
FROM 
 OldCustomerTable  OCT INNER JOIN Address A
  ON OCT.CustomerID = A.CustomerID
WHERE
  OCT.Address1 != A.Address1 
  OR OCT.Address2 != A.Address2
  OR OCT.Address3 != A.Address3

ИЛИ OCT.Address4! = A.Address4

Вы можете дополнительно проверить, что новая таблица адресов содержит только 1 адрес для каждого клиента

SELECT
 CustomerID
 , COUNT(AddressID)
FROM
 Address
GROUP BY
 CustomerID
HAVING
 COUNT(AddressID) >1
0 голосов
/ 31 января 2009

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

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

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