Стратегии разработки и развертывания баз данных (C#)

Скотт Митчелл

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

Введение

Как обсуждалось в предыдущих руководствах, развертывание приложения ASP.NET влечет за собой копирование соответствующего содержимого из среды разработки в рабочую среду. Развертывание — это не однократное событие, а то, что происходит каждый раз при выпуске новой версии программного обеспечения или при обнаружении и исправлении ошибок или проблем безопасности. При копировании ASP.NET страниц, изображений, файлов JavaScript и других подобных файлов в рабочую среду вам не нужно беспокоиться о том, как эти файлы были изменены с момента последнего развертывания. Вы можете слепо скопировать файл в рабочую среду, перезаписав существующее содержимое. К сожалению, эта простота не распространяется на развертывание базы данных.

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

Проблемы развертывания базы данных

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

Между развертываниями базы данных разработки и рабочей базы данных могут быть не синхронизированы. Хотя схема рабочей базы данных остается неизменной, схема базы данных разработки может измениться по мере добавления новых функций. Вы можете добавлять или удалять столбцы, таблицы, представления или хранимые процедуры. Кроме того, могут быть важные данные, которые добавляются в базу данных разработки. Многие приложения, управляемые данными, включают таблицы подстановки, заполненные жестко заданными данными приложения, которые не доступны для редактирования пользователем. Например, на веб-сайте аукциона может быть раскрывающийся список с вариантами, описывающими состояние выставленного на аукционе товара: "Новый", "Новый", "Хороший" и "Справедливый". Вместо жесткого программирования этих параметров непосредственно в раскрывающемся списке обычно лучше поместить их в таблицу базы данных. Если во время разработки в таблицу добавляется новое условие с именем Poor, то при развертывании приложения эту же запись необходимо добавить в таблицу подстановки в рабочей базе данных.

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

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

Определение базового плана

Чтобы сохранить изменения в базе данных приложения, необходимо иметь некоторое начальное состояние— базовый план, к которому применяются изменения. С одной стороны, начальным состоянием может быть пустая база данных без таблиц, представлений или хранимых процедур. Такой базовый план приводит к созданию большого журнала изменений, так как он должен включать создание всех таблиц, представлений и хранимых процедур базы данных, а также любые изменения, внесенные после первоначального развертывания. На другом конце спектра можно задать базовый план в качестве версии базы данных, которая изначально развернута в рабочей среде. Этот вариант приводит к гораздо меньшему размеру журнала изменений, так как он включает только изменения, внесенные в базу данных после первого развертывания. Это подход, который я предпочитаю. И, конечно, вы можете выбрать более середину пути, определив базовый план как точку между первоначальным созданием базы данных и первым развертыванием базы данных.

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

В вашем распоряжении есть множество средств для создания скрипта SQL базовой версии. В SQL Server Management Studio (SSMS) можно щелкнуть базу данных правой кнопкой мыши, перейти к подменю Задачи и выбрать параметр Создать скрипты. При этом запустится мастер сценариев, в котором можно указать создать файл, содержащий команды SQL для создания объектов базы данных. Другой вариант — мастер публикации баз данных, который может создавать команды SQL для создания не только схемы базы данных, но и данных в таблицах базы данных. Мастер публикации баз данных был подробно рассмотрен еще в руководстве По развертыванию базы данных . Независимо от того, какое средство вы используете, в конечном итоге у вас должен быть файл скрипта, который можно использовать для повторного создания базовой версии базы данных, если возникнет такая необходимость.

Документирование изменений базы данных в прозе

Самый простой способ вести журнал изменений в модели данных на этапе разработки — записать изменения в прозе. Например, если во время разработки уже развернутого приложения вы добавляете новый столбец в Employees таблицу, удаляете столбец из Orders таблицы и добавляете новую таблицу (ProductCategories), вы будете хранить текстовый файл или документ Microsoft Word со следующим журналом:

Изменить дату Сведения об изменении
2009-02-03: Добавлен столбец DepartmentID (int, NOT NULL) в таблицу Employees . Добавлено ограничение внешнего ключа от Departments.DepartmentID до Employees.DepartmentID.
2009-02-05: Удален столбец TotalWeight из Orders таблицы. Данные, уже зарегистрированные в связанных OrderDetails записях.
2009-02-12: Создали таблицу ProductCategories . Существует три столбца: ProductCategoryID (int, IDENTITY, ), CategoryNameNOT NULL(nvarchar(50), NOT NULL) и Active (bit, NOT NULL). Добавлено ограничение первичного ключа для ProductCategoryIDи значение по умолчанию 1 в Activeзначение .

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

Основным преимуществом документирования изменений базы данных в прозе является простота. Для создания и изменения объектов базы данных не требуется знание синтаксиса SQL. Вместо этого можно записать изменения в прозе и реализовать их с помощью графического пользовательского интерфейса SQL Server Management Studio.

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

Примечание

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

Запись инструкций изменения SQL

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

Синтаксис SQL включает ряд инструкций для создания и изменения различных объектов базы данных. Например, при выполнении инструкции CREATE TABLE создается новая таблица с указанными столбцами и ограничениями. Инструкция ALTER TABLE изменяет существующую таблицу, добавляя, удаляя или изменяя ее столбцы или ограничения. Существуют также инструкции для создания, изменения и удаления индексов, представлений, определяемых пользователем функций, хранимых процедур, триггеров и других объектов базы данных.

Возвращаясь к предыдущему примеру, вы видите, что во время разработки уже развернутого приложения вы добавляете новый столбец в Employees таблицу, удаляете Orders столбец из таблицы и добавляете новую таблицу (ProductCategories). Такие действия приводят к созданию файла журнала изменений со следующими командами SQL:

-- Add the DepartmentID column 

ALTER TABLE [Employees] ADD [DepartmentID] 
int NOT NULL 

-- Add a foreign key constraint between Departments.DepartmentID and Employees.DepartmentID
ALTER TABLE [Employees] ADD 
CONSTRAINT [FK_Departments_DepartmentID]
      FOREIGN 
KEY ([DepartmentID]) 
      REFERENCES 
[Departments] ([DepartmentID]) 

-- Remove TotalWeight column from Orders
ALTER TABLE [Orders] DROP COLUMN 
[TotalWeight] 

-- Create the ProductCategories table

CREATE TABLE [ProductCategories]
(
      [ProductCategoryID] 
int IDENTITY(1,1) NOT NULL,
      [CategoryName] 
nvarchar(50) NOT NULL,
      [Active] 
bit NOT NULL CONSTRAINT [DF_ProductCategories_Active]  DEFAULT 
((1)),
      CONSTRAINT 
[PK_ProductCategories] PRIMARY KEY CLUSTERED ( [ProductCategoryID])
)

Отправка этих изменений в рабочую базу данных во время развертывания выполняется одним щелчком мыши: откройте SQL Server Management Studio, подключитесь к рабочей базе данных, откройте окно Новый запрос, вставьте содержимое журнала изменений и нажмите кнопку Выполнить, чтобы запустить скрипт.

Использование средства сравнения для синхронизации моделей данных

Документировать изменения базы данных в прозе легко, но для реализации изменений требуется, чтобы разработчик вносит каждое изменение в рабочую базу данных по одному за раз; Документирование команд SQL change делает реализацию этих изменений в рабочей базе данных так же просто и быстро, как нажатие кнопки, но требует изучения и освоения инструкций SQL и синтаксиса для создания и изменения объектов базы данных. Средства сравнения баз данных берут лучшее из обоих подходов и отбрасывают худшие.

Средство сравнения баз данных сравнивает схему или данные двух баз данных и отображает сводный отчет о различиях баз данных. Затем нажатием кнопки можно создать команды SQL для синхронизации одного или нескольких объектов базы данных. В двух словах можно использовать средство сравнения баз данных для разработки и рабочей базы данных во время развертывания, создав файл, содержащий команды SQL, которые при выполнении будут применять изменения к схеме рабочей базы данных, чтобы она отражала схему базы данных разработки.

Существует множество сторонних средств сравнения баз данных, предлагаемых различными поставщиками. Одним из таких примеров является SQL Compare от Red Gate Software. Рассмотрим процесс использования sql Compare для сравнения и синхронизации схем баз данных разработки и рабочей базы данных.

Примечание

На момент написания этой статьи текущая версия SQL Compare была версии 7.1, а Standard Edition стоила 395 долл. США. Вы можете следовать инструкциям, скачав бесплатную 14-дневную пробную версию.

Когда sql Compare запускается, откроется диалоговое окно Проекты сравнения, в котором отображаются сохраненные проекты сравнения SQL. Создайте новый проект. Откроется мастер настройки проекта, который запрашивает сведения о базах данных для сравнения (см. рис. 1). Введите сведения для баз данных среды разработки и рабочей среды.

Сравнение баз данных разработки и рабочей базы данных

Рис. 1. Сравнение баз данных разработки и рабочей среды (щелкните для просмотра полноразмерного изображения)

Примечание

Если база данных среды разработки является файлом базы данных SQL Express Edition в App_Data папке веб-сайта, необходимо зарегистрировать базу данных на сервере базы данных SQL Server Express, чтобы выбрать ее в диалоговом окне, показанном на рисунке 1. Самый простой способ сделать это — открыть SQL Server Management Studio (SSMS), подключиться к серверу базы данных SQL Server Express и подключить базу данных. Если на компьютере не установлена среда SSMS, вы можете скачать и установить бесплатную SQL Server Management Studio.

Помимо выбора баз данных для сравнения, можно также указать различные параметры сравнения на вкладке Параметры. Один из вариантов, который может потребоваться включить, — "Игнорировать ограничения и имена индексов". Напомним, что в предыдущем руководстве мы добавили объекты базы данных служб приложений в базы данных разработки и рабочей среды. Если вы использовали средство для aspnet_regsql.exe создания этих объектов в рабочей базе данных, вы обнаружите, что имена ограничений первичного ключа и уникальные в разных базах данных разработки и рабочей базы данных различаются. Следовательно, sql Compare помечает все таблицы служб приложений как разные. Вы можете оставить флажок "Игнорировать имена ограничений и индексов" и синхронизировать имена ограничений или поручить SQL Compare игнорировать эти различия.

Выбрав базы данных для сравнения (и просмотрив параметры сравнения), нажмите кнопку Сравнить, чтобы начать сравнение. В течение следующих нескольких секунд sql Compare проверяет схемы двух баз данных и создает отчет об их отличиях. Я намеренно внес некоторые изменения в базу данных разработки, чтобы показать, как такие несоответствия отмечены в интерфейсе сравнения SQL. Как показано на рисунке 2, я добавил BirthDate столбец в Authors таблицу, удалил ISBN столбец из Books таблицы и добавил новую таблицу , которая позволяет пользователям, Ratingsпосещающим сайт, оценивать рецензируемые книги.

Примечание

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

Сравнение SQL Списки различия между базами данных разработки и рабочей базой данных

Рис. 2. Сравнение sql Списки различия между базами данных разработки и рабочей базой данных (щелкните для просмотра полноразмерного изображения)

Sql Compare разбивает объекты базы данных на группы, быстро показывая, какие объекты существуют в обеих базах данных, но отличаются, какие объекты существуют в одной базе данных, а какие — идентичны. Как видите, существует два объекта, которые существуют в обеих базах данных, но отличаются: Authors таблица, к которой был добавлен столбец, и Books таблица, в которой был удален один. Существует один объект, который существует только в базе данных разработки, а именно только что созданная Ratings таблица. Кроме того, в обеих базах данных имеется 117 объектов, идентичных.

При выборе объекта базы данных отображается окно Различия SQL, в котором показано, чем отличаются эти объекты. В окне Отличия SQL, которое отображается внизу на рисунке 2, подчеркивается, что Authors таблица в базе данных разработки содержит BirthDate столбец, который не найден в Authors таблице рабочей базы данных.

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

Использование мастера синхронизации для синхронизации схем баз данных

Рис. 3. Использование мастера синхронизации для синхронизации схем баз данных (щелкните для просмотра полноразмерного изображения)

Средства сравнения баз данных, такие как Сравнение SQL Red Gate Software, упрощают применение изменений к схеме базы данных разработки к рабочей базе данных.

Примечание

Sql Compare сравнивает и синхронизирует схемы двух баз данных. К сожалению, он не сравнивает и не синхронизирует данные в двух таблицах баз данных. Red Gate Software предлагает продукт sql Data Compare , который сравнивает и синхронизирует данные между двумя базами данных, но это отдельный продукт от сравнения SQL и стоит еще 395 долл. США.

Перевод приложения в автономный режим во время развертывания

Как мы видели в этих руководствах, развертывание состоит из нескольких этапов: копирование страниц ASP.NET, страниц master, CSS-файлов, файлов JavaScript, изображений и другого необходимого содержимого из среды разработки в рабочую среду, копирование сведений о конфигурации рабочей среды, если это необходимо, и применение изменений в модели данных с момента последнего развертывания. В зависимости от количества файлов и сложности изменений базы данных эти действия могут занять от нескольких секунд до нескольких минут. В этом окне веб-приложение находится в потоке, и пользователи, посещающие сайт, могут столкнуться с ошибками или непредвиденным поведением.

При развертывании веб-сайта рекомендуется перевести веб-приложение в автономный режим до завершения развертывания. Вывести приложение в автономный режим (и создать его резервную копию после завершения развертывания) так же просто, как отправить файл, а затем удалить его. Начиная с ASP.NET 2.0, простое наличие файла с именем app_offline.htm в корневом каталоге приложения переносит весь веб-сайт в автономный режим. На любой запрос к странице ASP.NET на этом сайте автоматически отправляется ответ с содержимым app_offline.htm файла. После удаления этого файла приложение вернется в режим "в сети".

Таким образом, вывести приложение в автономный режим во время развертывания так же просто, как отправить app_offline.htm файл в корневой каталог рабочей среды перед началом процесса развертывания, а затем удалить его (или переименовать в другое) после завершения развертывания. Дополнительные сведения об этом методе см. в статье Джона Петерсона "Перевод приложения ASP.NET в автономном режиме".

Сводка

Задача main при развертывании управляемых данными приложений заключается в развертывании базы данных. Так как существует две версии базы данных — одна в среде разработки и одна в рабочей среде, эти две схемы баз данных могут перестать синхронизироваться при добавлении новых функций в разработку. Более того, так как рабочая база данных заполняется реальными данными от реальных пользователей, нельзя перезаписать рабочую базу данных измененной базой данных разработки, как при развертывании файлов, составляющих приложение (ASP.NET страниц, файлов изображений и т. д.). Вместо этого развертывание базы данных влечет за собой реализацию точного набора изменений, внесенных в базу данных разработки в рабочей базе данных с момента последнего развертывания.

В этом руководстве рассматривается три метода ведения и применения журнала изменений базы данных. Самый простой подход — записать изменения в прозе. Хотя эта тактика делает реализацию этих изменений в рабочей базе данных процессом вручную, она не требует знания команд SQL для создания и изменения объектов базы данных. Более сложный подход, который является гораздо более приемлемым в крупных проектах или проектах с несколькими разработчиками, заключается в записи изменений в виде серии команд SQL. Это значительно ускоряет развертывание этих изменений в целевой базе данных. Лучшее из обоих подходов можно достичь с помощью средства сравнения баз данных, такого как Сравнение SQL Red Gate Software.

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

Счастливого программирования!