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

Методология контроля версий SQL

Есть несколько вопросов о SO о контроле версий для SQL и множестве ресурсов в Интернете, но я не могу найти то, что полностью охватывает то, что я пытаюсь сделать.

Во-первых, я говорю о методологии здесь. Я знаком с различными приложениями для управления версиями, и я знаком с такими инструментами, как Red Gate SQL Compare и т.д., И я знаю, как писать приложение, чтобы автоматически проверять ситуацию в моей исходной системе управления. Если есть инструмент, который был бы особенно полезен при создании целой новой методологии или который имел бы полезную и необычную функциональность, тогда отлично, но для задач, упомянутых выше, я уже установлен.

Требования, которые я пытаюсь выполнить, следующие:

  • Данные схемы базы данных и справочной таблицы версий
  • Сценарии DML для исправлений данных для больших таблиц версий
  • Сервер может быть продвинут от версии N до версии N + X, где X не всегда может быть 1
  • Код не дублируется в системе управления версиями - например, если я добавлю столбец в таблицу, я не хочу, чтобы это было сделано как в create script, так и в файле alter script
  • Система должна поддерживать несколько клиентов, которые находятся в разных версиях для приложения (пытаясь получить их все в пределах 1 или 2 релизов, но еще нет)

Некоторые организации сохраняют инкрементные скрипты изменений в своем управлении версиями и, чтобы получить от версии N до N + 3, вам нужно будет запускать скрипты для N- > N + 1, затем N + 1- > N + 2, затем N + 2- > N + 3. Некоторые из этих сценариев могут повторяться (например, добавляется столбец, но затем он изменяется для изменения типа данных). Мы стараемся избегать такой повторяемости, поскольку некоторые из клиентских БД могут быть очень большими, поэтому эти изменения могут занять больше времени, чем необходимо.

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

Возможно, есть гибридное решение? Может быть, я просто прошу слишком много? Любые идеи или предложения были бы весьма полезны.

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

Спасибо!

4b9b3361

Ответ 1

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

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

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

Конечно, этот метод накладывает несколько требований на дизайн базы данных:

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

Примеры из недавнего проекта:

001.sql:

if object_id(N'dbo.Registrations') is null 
begin
    create table dbo.Registrations
    (
        [Id]                    uniqueidentifier not null,
        [SourceA]               nvarchar(50)     null,
        [SourceB]               nvarchar(50)     null,
        [Title]                 nvarchar(50)     not null,
        [Occupation]            nvarchar(50)     not null,
        [EmailAddress]          nvarchar(100)    not null,
        [FirstName]             nvarchar(50)     not null,
        [LastName]              nvarchar(50)     not null,
        [ClinicName]            nvarchar(200)    not null,
        [ClinicAddress]         nvarchar(50)     not null,
        [ClinicCity]            nvarchar(50)     not null,
        [ClinicState]           nchar(2)         not null,
        [ClinicPostal]          nvarchar(10)     not null,
        [ClinicPhoneNumber]     nvarchar(10)     not null,
        [ClinicPhoneExtension]  nvarchar(10)     not null,
        [ClinicFaxNumber]       nvarchar(10)     not null,
        [NumberOfVets]          int              not null,  
        [IpAddress]             nvarchar(20)     not null,
        [MailOptIn]             bit              not null,
        [EmailOptIn]            bit              not null,
        [Created]               datetime         not null,
        [Modified]              datetime         not null,
        [Deleted]               datetime         null
    );
end

if not exists(select 1 from information_schema.table_constraints where constraint_name = 'pk_registrations')
    alter table dbo.Registrations add
        constraint pk_registrations primary key nonclustered (Id);

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_created')
    create clustered index ix_registrations_created
        on dbo.Registrations(Created);

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_email')
    create index ix_registrations_email
        on dbo.Registrations(EmailAddress);

if not exists (select 1 from sysindexes where [name] = 'ix_registrations_email')
    create index ix_registrations_name_and_clinic
        on dbo.Registrations (FirstName,
                              LastName,
                              ClinicName);

002.sql

/**********************************************************************
  The original schema allowed null for these columns, but we don't want
  that, so update existing nulls and change the columns to disallow 
  null values
 *********************************************************************/

update dbo.Registrations set SourceA = '' where SourceA is null;
update dbo.Registrations set SourceB = '' where SourceB is null;
alter table dbo.Registrations alter column SourceA nvarchar(50) not null;
alter table dbo.Registrations alter column SourceB nvarchar(50) not null;

/**********************************************************************
  The client wanted to modify the signup form to include a fax opt-in
 *********************************************************************/

if not exists 
(
    select 1 
      from information_schema.columns
     where table_schema = 'dbo'
       and table_name   = 'Registrations'
       and column_name  = 'FaxOptIn'
)
alter table dbo.Registrations 
    add FaxOptIn bit null 
        constraint df_registrations_faxoptin default 0;

003.sql, 004.sql и т.д.

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

Ответ 2

У вас довольно строгий набор требований, я не уверен, найдёте ли вы что-то, что помещает проверки во все поля, особенно несколько параллельных схем и интеллектуальный контроль версий.

Самый многообещающий инструмент, который я прочитал об этом типе приманок, Liquibase.
Вот несколько дополнительных ссылок:

Ответ 3

Да, вы много просите, но все они действительно уместны! Здесь, в Red Gate, мы продвигаемся к полному решению по разработке базы данных с помощью расширения SSMS для управления SQL Server, и мы сталкиваемся с аналогичными проблемами.

http://www.red-gate.com/products/SQL_Source_Control/index.htm

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

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

Ответ 4

для этой проблемы используйте Team Team 2008 2008 для контроля версий вашей базы данных sql.

В tsf нет. функции avialbe, как

  • Datacompare
  • Schemacompare
  • контроль версий

об управлении версией базы данных: http://www.codinghorror.com/blog/2006/12/is-your-database-under-version-control.html для более подробной проверки: http://msdn.microsoft.com/en-us/library/ms364062(VS.80).aspx

Ответ 5

Мы используем SQL Examiner для хранения схемы базы данных под контролем версий. Я тоже пробовал VS2010, но, на мой взгляд, подход VS слишком сложный для небольших и средних проектов. С SQL Examiner я в основном работаю с SSMS и использую SQL Examiner для регистрации обновлений SVN (поддерживаются также TFS и SourceSafe, но я никогда не пробовал).

Вот описание подхода SQL Examiner: Как получить вашу базу данных под контролем версий

Ответ 6

Попробуйте DBSourceTools. (http://dbsourcetools.codeplex.com)
Его открытый исходный код и специально разработанный для script всей базы данных - таблицы, представления, procs на диск, а затем повторно создайте эту базу данных с помощью цели развертывания.
Вы можете script все данные или просто указать, какие таблицы для script данных для.
Кроме того, вы можете распечатать результаты для распространения.
Мы используем его для контроля версий баз данных и тестирования обновлений для новых выпусков.
В back-end он построен вокруг SMO и, таким образом, поддерживает SQL 2000, 2005 и 2008.
DBDiff интегрирован, чтобы сравнить схемы.
Повеселись, - Натан.