Вы кладете статические данные вашей базы данных в систему контроля версий? Как? - PullRequest
18 голосов
/ 06 октября 2009

Я использую SQL-Server 2008 с Visual Studio Database Edition.

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

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

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

  • статические данные . например. список товаров, заполняющий выпадающий список. Программа не полагается на наличие определенного продукта в списке для работы. Это может быть, например, список продуктов в кодировке Unicode, которые должны быть развернуты в производстве при развертывании новой «версии Unicode» программы.

  • другие данные , т. Е. Все остальное (журналы, учетные записи пользователей, данные пользователей и т. Д.)

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

Но что касается статических данных, мне интересно, что делать.

  • Должен ли я добавить сценарии вставки в сценарии создания? или, может быть, использовать отдельные сценарии?

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

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

Как вы управляете статическими данными вашей БД?

Ответы [ 9 ]

7 голосов
/ 24 октября 2009

Я объяснил технику, которую я использовал в своем блоге Контроль версий и Ваша база данных . Я использую метаданные базы данных (в данном случае расширенные свойства SQL Server) для хранения версии развернутого приложения. У меня есть только сценарии, которые обновляются от версии к версии. При запуске приложение считывает развернутую версию из метаданных базы данных (отсутствие метаданных интерпретируется как версия 0, т. Е. Ничего еще не развернуто). Для каждой версии есть функция приложения, которая обновляется до следующей версии. Обычно эта функция запускает сценарий T-SQL внутреннего ресурса, который выполняет обновление, но это может быть что-то другое, например, развертывание сборки CLR в базе данных.

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

У этой техники есть несколько преимуществ:

  • Мне легко протестировать новую версию. У меня есть резервная копия предыдущей версии, я применяю сценарий обновления, затем я могу вернуться к предыдущей версии, изменить сценарий, повторить попытку, пока я не буду удовлетворен результатом.
  • Мое приложение может быть развернуто поверх любой предыдущей версии. Различные клиенты имеют различные развернутые версии. Когда они обновляются, мое приложение поддерживает обновление с любой предыдущей версии.
  • Нет никакой разницы между новой установкой и обновлением, он запускает один и тот же код, поэтому у меня меньше путей кода для обслуживания и тестирования.
  • Нет разницы между изменениями в DML и DDL (ваш первоначальный вопрос). все они обрабатываются одинаково, так как скрипт запускается для перехода с одной версии на другую. Когда мне нужно внести изменение, как вы описываете (изменить значение по умолчанию), я фактически увеличиваю версию схемы , даже если никакое другое изменение DDL не происходит . Таким образом, в версии 5.1 по умолчанию было «foo», в 5.2 по умолчанию «bar» , и это единственное различие между двумя версиями , а шаг «upgrade» - это просто инструкция UPDATE (после Конечно, с помощью изменения метаданных версии, т.е. sp_updateextendedproperty).
  • Все изменения находятся в системе контроля версий, являющейся частью исходных кодов приложений (в основном скрипты T-SQL).
  • Я легко могу получить любую предыдущую версию схемы, например. чтобы воспроизвести жалобу клиента, просто запустив последовательность обновления и остановившись на интересующей меня версии.

Этот подход несколько раз спасал мою кожу, и теперь я истинный сторонник. Есть только один недостаток: в источнике нет очевидного места для поиска «какова текущая форма процедуры foo?». Поскольку последняя версия foo могла быть обновлена ​​2 или 3 версии назад, и с тех пор она не изменялась, мне нужно взглянуть на скрипт обновления для этой версии. Я обычно прибегаю к тому, чтобы просто заглянуть в базу данных и посмотреть, что там есть, а не искать по сценариям обновления.

Последнее замечание: на самом деле это не мое изобретение. Это смоделировано точно после того, как сам SQL Server обновляет метаданные базы данных (mssqlsystemresource).

2 голосов
/ 24 октября 2009

Здесь, в Red Gate, мы недавно добавили в SQL Data Compare функцию, позволяющую хранить статические данные в виде DML (один файл .sql для каждой таблицы) вместе со схемой DDL, которая в настоящее время поддерживается SQL Compare.

Чтобы понять, как это работает, вот диаграмма , которая объясняет, как это работает.

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

Дэвид Аткинсон, менеджер по продукту, Red Gate Software

2 голосов
/ 06 октября 2009

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

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

1 голос
/ 06 октября 2009

Решением, которое я использую, является создание и изменение сценариев в системе контроля версий в сочетании с информацией о версии, хранящейся в базе данных.

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

1 голос
/ 06 октября 2009

Во-первых, я никогда не использовал Visual Studio Database Edition. Вы благословлены (или прокляты) всеми инструментами, которые дает вам эта утилита. Надеюсь, это включает в себя большую гибкость.

Я не знаю, что я бы сильно изменил между статическими данными вашего типа 1 и типа 2. Это наборы данных, которые определяются один раз, а затем никогда не обновляются, за исключением последующих выпусков и обновлений, верно? В этом случае основное различие заключается в том, как или почему данные являются такими, какие они есть, а не в том, как они хранятся или инициализируются. (Если данные не зависят от среды, как в «A» для разработки, «B» для производства. Это будут данные «типа 4», и я буду с радостью игнорировать их в этом посте, потому что я решил их с помощью SQLCMD переменные, и они вызывают у меня головную боль.)

Во-первых, я бы сделал скрипт для создания всех таблиц в базе данных - желательно только один скрипт, в противном случае вы можете иметь кучу скриптов (и найти и заменить, когда переименование столбцов становится очень неудобным). Затем я бы сделал скрипт для заполнения статических данных в этих таблицах. Этот сценарий можно добавить в конец сценария таблицы, создать собственный сценарий или даже создать один сценарий для таблицы - хорошая идея, если вам нужно загрузить сотни или тысячи строк. (Некоторые люди создают CSV-файл, а затем выдают на него BULK INSERT, но я бы хотел избежать этого, поскольку он просто дает вам два файла и сложный процесс [настройка сопоставлений дисков при развертывании] для управления.)

Главное, что нужно помнить, это то, что данные (хранящиеся в базах данных) могут и будут меняться со временем. Редко (если вообще когда-нибудь!) Вам будет предоставлена ​​возможность удалить вашу производственную базу данных и заменить ее новой, блестящей, новой, лишенной всех этих грубых данных за прошедшие тринадцать лет. Базы данных - все об изменениях с течением времени, и вот где скрипты вступают в свои права. Вы начинаете со сценариев для создания базы данных, а затем со временем добавляете сценарии, которые изменяют базу данных по мере появления изменений - и это также относится к вашим статическим данным (любого типа).

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

1 голос
/ 06 октября 2009

См. ответ этой темы . Статические данные из ваших первых двух точек должны находиться под контролем источника, ИМХО.

Редактировать: * новый

  • все-в-одном или отдельный скрипт? это не имеет большого значения, если вы (команда разработчиков) согласны с вашей группой по развертыванию. Я предпочитаю разделять файлы, но я всегда могу создать all-in-one.sql из файлов в правильном порядке [Logins, Roles, Users; Tables; Views; Stored Procedures; UDFs; Static Data; (Audit Tables, Audit Triggers)]
  • как вы убедитесь, что они его выполняют : ну, сделайте это еще одним шагом в документации по развертыванию приложения / базы данных. Если вы запускаете приложение, которое действительно нуждается в определенных (новых) статических данных в базе данных, вы можете выполнить проверку версии БД в своем приложении. и вы обновляете DB_VERSION до вашего нового номера выпуска как часть этого скрипта. Затем ваше приложение при запуске должно проверить его и сообщить об ошибке, если требуется новая версия БД.
  • Статические данные dev и non-dev : Я никогда не видел этот случай на самом деле. Чаще всего это реальные статические данные , которые вы можете назвать "dev", которые представляют собой основные конфигурации, статические данные ISO и т. Д. Другой тип - данные поиска по умолчанию , которые существуют для пользователи для начала, но они могут добавить больше. Механизм ВСТАВКИ этих данных может быть другим, потому что вам нужно убедиться, что вы не уничтожаете (мощные) данные, созданные пользователем.
1 голос
/ 06 октября 2009

Для первых двух шагов вы могли бы рассмотреть возможность использования промежуточного формата (например, XML) для данных, затем использовать собственный инструмент или что-то вроде CodeSmith для генерации SQL, а также возможные исходные файлы, если (для пример) у вас есть таблицы поиска, которые относятся к перечислениям, используемым в коде - это помогает обеспечить согласованность.

Это имеет еще одно преимущество: если схема меняется, во многих случаях вам не нужно повторно генерировать все свои операторы INSERT - вы просто меняете инструмент.

1 голос
/ 06 октября 2009

Я сталкивался с этим при разработке систем CMS.

Я начал добавлять статические данные (материал, указанный в коде) в сценарии создания базы данных, а затем отдельный сценарий для добавления в любые «данные инициализации» (например, страны, начальная популяция продуктов и т. Д.).

1 голос
/ 06 октября 2009

Мне очень нравится ваше различие трех типов данных.

Я согласен на третий .

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

Если есть дополнительная информация, которую мы хотели бы иметь в базе данных, например, если она может быть изменена для сайта клиента, мы разделяем их. Другие таблицы могут по-прежнему ссылаться на эти данные (либо по индексу ex: 0, 1, 2, 3, либо по коду ex: EMPTY, SIMPLE, DOUBLE, ALL).

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


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

У нас есть полная процедура для этого, и readme приходит с каждым выпуском, со сценариями и так далее ...

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