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

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

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

Требования, которым я пытаюсь соответствовать:

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

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

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

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

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

Спасибо!


person Tom H    schedule 05.05.2010    source источник
comment
Не знаю, видели ли вы это, но я получил несколько разумных ответов: stackoverflow.com/questions/2401229/   -  person Paddy    schedule 05.05.2010
comment
Это помогает? msmvps.com/ blogs / deborahk / archive / 2010/05/02 / Обратите внимание, что внизу статьи есть дополнительные ссылки.   -  person Raj Kaimal    schedule 05.05.2010
comment
@Paddy - Спасибо за ссылку. У pdc было хорошее решение, которое соответствовало тому, которое мы рассматривали, но задачи по созданию скриптов переданы на аутсорсинг в Индию (не мой выбор), а опыт там ограничен, поэтому некоторые из более сложных кодов могут быть проблемой. Но пока он все еще на столе.   -  person Tom H    schedule 05.05.2010


Ответы (6)


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

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

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

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

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

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

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 и т. Д.

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

person Chris    schedule 06.05.2010
comment
Спасибо. Это похоже на то, что pdc опубликовал по ссылке от Paddy. Это то, что я пытался продать в течение последнего дня. Некоторые из присутствующих здесь людей все еще привязаны к идее модели базы данных с дополнительными метаданными, а затем используют инструмент сравнения вместе с дополнительными, но, возможно, я смогу их повлиять. Мой подход на самом деле по-прежнему сохраняет сценарии для одного объекта в одном файле, насколько это возможно, и по мере появления новых изменений они помещаются в этот файл вместо того, чтобы постоянно добавлять новые сценарии. Упорядочивание версий - единственная проблема, и я думаю, что у меня тоже есть решение. - person Tom H; 06.05.2010

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

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

person crowne    schedule 05.05.2010
comment
Спасибо за предложение. Да, определенно жесткий список требований, но я надеюсь :) Я посмотрю, на что способен LiquiBase. - person Tom H; 05.05.2010

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

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

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

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

person David Atkinson    schedule 06.05.2010

для такого рода проблем используйте Visual studio team system 2008 для контроля версий вашей базы данных sql.

В цф нет. функции avialbe like

  • Datacompare
  • Схема сравнения
  • контроль версий

об управлении версиями базы данных: 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

person Pranay Rana    schedule 05.05.2010

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

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

person SQLDev    schedule 12.05.2010
comment
Спасибо за предложение. К сожалению, это работает только при загрузке скриптов в вашу систему управления версиями. Моя проблема заключается во время развертывания - автоматизация этого для многих клиентов, использующих разные версии программного обеспечения. - person Tom H; 12.05.2010
comment
SQL Examiner сравнивает сценарии базы данных, хранящиеся в SVN, с целевой базой данных и создает сценарий миграции схемы. Кроме того, вы можете сравнить версию 10 в SVN с версией 12 в SVN и сгенерировать скрипт для переноса схемы из версии 10 в версию 12. - person SQLDev; 12.05.2010

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

person blorkfish    schedule 14.07.2010