Добавить элемент управления версиями в существующую базу данных SQL Server - программирование
Подтвердить что ты не робот

Добавить элемент управления версиями в существующую базу данных SQL Server

Я являюсь частью команды разработчиков, которая в настоящее время работает с базой данных, которая не имеет какого-либо контроля источника. Мы работаем с SQL Server 2008 R2 и всегда управляем БД непосредственно с помощью SSMS. Теперь он имеет ~ 340 таблиц и ~ 1600 хранимых процедур, а также несколько триггеров и просмотров, поэтому это не маленькая БД.

Моя цель состоит в том, чтобы иметь БД под контролем версий, поэтому я читал статьи, такие как серии Скотта Аллена и многие старые вопросы, связанные с СО. Но я все еще не могу решить, как действовать.

То, что я думаю, это script схема базы данных в одном файле, затем процедуры, триггеры и представления в каждом файле. Затем сохраните все версии под Mercurial. Но, конечно, каждый член команды может получить доступ к SSMS и напрямую изменить схему и процедуры с возможностью того, что любой из нас может забыть реплицировать эти изменения в версированных файлах.

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

4b9b3361

Ответ 1

Общий процесс

Мы создаем базовую линию для конкретной версии (например, v1.0). Базовая линия включает в себя одно полное создание схемы script, а также обновление script из разрешенных предыдущих версий, если оно есть (более подробно об этом в данный момент). Итак, для v1.0 у нас будет только один script:

baseline-v1.0.sql

Из этой базовой линии мы создаем сценарии инкрементного изменения, когда мы работаем с предыдущей базой. Эти сценарии создаются таким образом, что они являются реентерабельными, так что их можно безопасно запускать несколько раз (когда первый раз выполняется только какая-либо фактическая работа, см. Следующий параграф о том, как это сделать). Мы просто создаем файл для каждого изменения script с базовым именем и меткой времени (которую мы называем версией). Так, например, скажем, мы создаем два сценария изменений после базовой линии. У нас были бы следующие файлы:

baseline-v1.0.sql (for creating new installations)
baseline-v1.0-201211071220.sql (created on Nov. 7, 2012 at 12:20 PM UTC)
baseline-v1.0-201211122019.sql (created on Nov. 12, 2012 at 8:00 PM UTC)

Мы создаем таблицу schema_version, которая имеет два столбца: baseline и version. baseline - это некоторая метка (например, v1.0, упомянутая выше), а version - это только метка времени, когда было создано изменение script (мы решили сделать это, потому что создание произвольных номеров версий создавало раздражающие административные издержки, где временная метка проста в использовании). Поэтому перед запуском изменения script, мы проверяем, было ли добавлено изменение script, запросив его на baseline и version. Если он уже присутствует, просто вернитесь из script или что-то еще. В противном случае примените изменение и вставьте в таблицу schema_version, чтобы отметить завершенное изменение script.

Пример изменения script:

-- Created by <developer> on Nov. 7, 2012 at 12:20 PM UTC
declare @schema_baseline varchar(10), @schema_version varchar(12)

set @schema_baseline = 'v1.0'
set @schema_version = '201211071210'

if exists (select 1 from schema_version where baseline = @schema_baseline and version = @schema_version = @schema_version) return 0

-- begin change script

-- place your schema changes here

-- end change script

insert into schema_version(@schema_baseline, @schema_version)

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

Когда мы достигнем важной вехи на этапе разработки продукта, мы создаем новую базовую линию. Итак, мы создаем новую базовую линию script (опять же, это снимок базы данных в качестве базовой линии) плюс обновление script от предыдущей базовой линии. Итак, скажем, у нас есть новая базовая линия, v2.0, у нас были бы следующие файлы:

baseline-v2.0.sql (for creating new installations)
baseline-v2.0-upgrade-v1.0.sql (for upgrading from v1.0)

Затем процесс продолжается.

Как мы применяем изменения

Сценарии хранятся в исходном коде. У нас есть инструмент, который упаковывает эти файлы и автоматически обновляет базы данных, которые используют наши команды поддержки и установки. Инструмент вычисляет текущую базовую базу целевой базы данных и запрашивает у пользователя, хочет ли он перейти на базовую линию в пакете. Если это так, и существует действующий путь обновления из текущей версии, он применяет обновление script и обновляет schema_version.baseline и удаляет все записи для сценариев изменений из предыдущей базовой линии. Если база данных новая, она применяет регулярную базовую линию script. В любом случае, после достижения базовой линии, он применяет все сценарии изменений от базовой линии, которые присутствуют в пакете, по одному за раз, в порядке, в транзакции. Если конкретное изменение script завершается с ошибкой, оно откатывает последний набор изменений и ошибок. Мы смотрим на журнал, исправляем любые проблемы, а затем снова запускаем пакет. В этот момент он должен просто подобрать последнее изменение script, которое преуспело, экономя время.

Инструменты автоматизации и Diff

Мы не позволяем инструментам diff напрямую обновлять производственные базы данных. Это слишком рискованно. Разумеется, мы используем инструменты для разметки, чтобы помочь создать сценарии обновления и изменения, но как только мы их получим, мы их расчесываем, массируем, тестируем и т.д., Затем создаем обновление или изменяем script в соответствии с выше. Мы используем скрипты tools/shell для создания файлов изменений script и устанавливаем проверку плиты котла schema_version.

Предостережение

Это на самом деле довольно прямолинейно, и он работает хорошо. Единственный раз, когда это действительно сложно, с ветвями. По большей части, ветки обрабатываются хорошо. Если нам понадобится изменение script для конкретной работы ветки, он будет очень быстро складываться в магистрали, как только мы снова объединим ветку. Нет проблем. Там, где это сложно, когда две ветки пытаются делать подобные вещи или где одна ветка полагается на другую. Тем не менее, это проблема процесса и планирования. Если мы застряли в такой ситуации, мы просто создадим новую базовую линию (скажем v2.1), а затем обновим ветки соответственно.

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

Ответ 2

Я бы рекомендовал Инструменты данных SQL Server и/или проект базы данных Visual Studio SQL. Он будет реконструировать существующую БД на файлы кода (sql), которые могут контролироваться версиями, и дает много других тонкостей (публикация, сравнение и т.д.).

Ответ 3

Мы разработали SQL Source Control специально для решения проблемы, которую вы описываете. Он расширяет SSMS, чтобы обеспечить связь между объектами схемы SQL Server (и статическими данными) и существующей системой управления версиями.

http://www.red-gate.com/products/sql-development/sql-source-control/

Если вам нужна дополнительная информация, мы будем очень рады помочь (свяжитесь с [email protected])

Ответ 4

Было много дискуссий по этой теме на многих форумах разработчиков.

Что я сделал и нашел, что это самый простой и чистый способ сделать это:

  • Извлеките каждый DD-объект DDL в свой собственный файл, индексы и PK могут перейти в тот же файл, что и таблица, к которой они принадлежат. FKs, процедуры, представления, триггеры, все, что может пройти через несколько таблиц, идут в их собственном файле.

  • Упорядочить файлы DDL в dirs для каждого типа объекта (например, таблица, процедура, триггер, просмотр и т.д.)

  • Для таблиц, содержащих статические справочные данные (например, почтовый индекс или состояние), есть отдельный файл с кучей операторов вставки

  • Проверьте эту структуру каталогов на любой элемент управления версиями, который вы используете

  • Напишите script, который будет перемещаться по этой структуре каталогов, которая обрамляет вашу БД, отличает ее от фактического БД, на который вы указываете (извлечение схемы из системных таблиц), и применяйте различия с помощью операторов ALTER TABLE

  • Если у вас есть преобразования данных между релизами, например. в v1 у вас есть поле FirstAndLastName, а в v2 вы решили разбить его на FirstName и LastName, у вас будет некоторый массовый процесс переноса/обработки данных.

Я успешно управлял изменениями БД в нескольких заданиях с использованием нескольких различных РСУБД. Обычно я использую Perl для script, который различает схему DB и файлы DDL на вашем изображении. Есть некоторые предположения к этому методу, и один из них заключается в том, что вы никогда не вносите никаких изменений в БД непосредственно в БД, а в своих файлах DDL, а затем запускаете script, чтобы применить его. Если вы сделаете это по-другому, они будут отменены, когда вы запустите script. Поэтому для этого требуется определенное командное соглашение и дисциплина. Ваше перемещение может отличаться.

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

Ответ 5

Наша система управления версиями Sql Historian может помочь людям с этой проблемой, особенно в ситуации, когда вы указываете, когда товарищи по команде "забывают" проверить код после того, как они обновили сервер.

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