Механизмы отслеживания изменений схемы БД

Каковы лучшие методы отслеживания и / или автоматизации изменений схемы БД? Наша команда использует Subversion для контроля версий, и таким образом мы смогли автоматизировать некоторые из наших задач (отправка сборок на промежуточный сервер, развертывание проверенного кода на производственном сервере), но мы по-прежнему выполняем обновления базы данных вручную. Я хотел бы найти или создать решение, которое позволит нам эффективно работать на серверах с разными средами, продолжая использовать Subversion в качестве бэкэнда, через который обновления кода и БД передаются на разные серверы.

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

Хотя решение, поддерживающее несколько платформ, было бы предпочтительнее, нам определенно необходимо поддерживать стек Linux / Apache / MySQL / PHP, поскольку большая часть нашей работы выполняется на этой платформе.

Ответов (20)

Решение

В мире Rails существует концепция миграций, сценариев, в которых изменения в базе данных выполняются на Ruby, а не на специфической для базы данных разновидности SQL. Ваш код миграции Ruby в конечном итоге преобразуется в DDL, специфичный для вашей текущей базы данных; это упрощает переключение платформ баз данных.

Для каждого изменения, которое вы вносите в базу данных, вы пишете новую миграцию. Миграции обычно имеют два метода: метод «вверх», в котором применяются изменения, и метод «вниз», при котором изменения отменяются. Одна команда обновляет базу данных, а также может использоваться для приведения базы данных к определенной версии схемы. В Rails миграции хранятся в собственном каталоге в каталоге проекта и проверяются в системе контроля версий, как и любой другой код проекта.

Это руководство Oracle по миграции Rails довольно хорошо описывает миграции .

Разработчики, использующие другие языки, рассмотрели миграции и реализовали свои собственные версии для конкретных языков. Я знаю Ruckusing , систему миграции PHP, созданную по образцу миграции Rails; это может быть то, что вы ищете.

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

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

С помощью этого сценария вы можете интегрировать его с DBUnit или каким-либо другим сценарием сборки, поэтому кажется, что он может вписаться в ваши уже автоматизированные процессы.

Проблема здесь действительно в том, чтобы разработчикам было легко записать собственные локальные изменения в систему управления версиями, чтобы поделиться ими с командой. Я сталкивался с этой проблемой много лет и был вдохновлен функциональностью Visual Studio для профессионалов в области баз данных. Если вам нужен инструмент с открытым исходным кодом с такими же функциями, попробуйте следующее: http://dbsourcetools.codeplex.com/ Удачи, - Натан.

ИМХО миграции имеют огромную проблему:

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

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

Попробуйте db-deploy - в основном инструмент Java, но работает и с php.

Если вы используете C#, обратите внимание на Subsonic, очень полезный инструмент ORM, который также генерирует sql-скрипт для воссоздания вашей схемы и \ или данных. Затем эти сценарии можно поместить в систему управления версиями.

http://subsonicproject.com/

Я создаю папки, названные в честь версий сборки, и помещаю туда скрипты обновления и понижения. Например, у вас могут быть следующие папки: 1.0.0, 1.0.1 и 1.0.2. Каждый из них содержит сценарий, позволяющий обновлять или понижать версию базы данных между версиями.

Если клиент или заказчик позвонит вам по поводу проблемы с версией 1.0.1, а вы используете 1.0.2, возврат базы данных к его версии не будет проблемой.

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

Как и сказал Джоуи, если вы находитесь в мире Rails, используйте Migrations. :)

Моя команда записывает все изменения базы данных и фиксирует эти сценарии в SVN вместе с каждым выпуском приложения. Это позволяет вносить инкрементальные изменения в базу данных без потери данных.

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

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

Мы используем очень простое, но эффективное решение.

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

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

Итак, в нашем программном обеспечении у нас есть что-то вроде этого:

RegisterUpgrade(1, 'ALTER TABLE XX ADD XY CHAR(1) NOT NULL;');

Этот код проверяет, находится ли база данных в версии 1 (которая хранится в таблице, созданной автоматически), если она устарела, команда выполняется.

Чтобы обновить файл metadata.sql в репозитории, мы запускаем это обновление локально, а затем извлекаем полные метаданные базы данных.

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

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

Я использовал следующую структуру проекта базы данных в Visual Studio для нескольких проектов, и она работала очень хорошо:

База данных

Сценарии изменения

0.PreDeploy.sql

1.SchemaChanges.sql

2.DataChanges.sql

3. разрешения.sql

Создать скрипты

Sprocs

Функции

Просмотры

Наша система сборки затем обновляет базу данных от одной версии к другой, выполняя сценарии в следующем порядке:

1.PreDeploy.sql

2.SchemaChanges.sql

Содержимое папки Create Scripts

2.DataChanges.sql

3. разрешения.sql

Каждый разработчик проверяет свои изменения на наличие определенной ошибки / функции, добавляя свой код в конец каждого файла. Когда основная версия завершена и разветвлена ​​в системе управления версиями, содержимое файлов .sql в папке Change Scripts удаляется.

We use something similar to bcwoord to keep our database schemata synchronized across 5 different installations (production, staging and a few development installations), and backed up in version control, and it works pretty well. I'll elaborate a bit:


To synchronize the database structure, we have a single script, update.php, and a number of files numbered 1.sql, 2.sql, 3.sql, etc. The script uses one extra table to store the current version number of the database. The N.sql files are crafted by hand, to go from version (N-1) to version N of the database.

They can be used to add tables, add columns, migrate data from an old to a new column format then drop the column, insert "master" data rows such as user types, etc. Basically, it can do anything, and with proper data migration scripts you'll never lose data.

Скрипт обновления работает так:

  • Подключитесь к базе данных.
  • Сделайте резервную копию текущей базы данных (потому что все пойдет не так) [mysqldump].
  • Создайте бухгалтерскую таблицу (называемую _meta), если она не существует.
  • Считать текущую ВЕРСИЮ из таблицы _meta. Принять 0, если не найден.
  • Для всех файлов .sql с номерами выше ВЕРСИИ выполните их по порядку.
  • Если один из файлов выдал ошибку: откатитесь к резервной копии
  • В противном случае обновите версию в бухгалтерской таблице до самого высокого исполняемого файла .sql.

Everything goes into source control, and every installation has a script to update to the latest version with a single script execution (calling update.php with the proper database password etc.). We SVN update staging and production environments via a script that automatically calls the database update script, so a code update comes with the necessary database updates.

We can also use the same script to recreate the entire database from scratch; we just drop and recreate the database, then run the script which will completely repopulate the database. We can also use the script to populate an empty database for automated testing.


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

Однако будьте осторожны при вставке запросов из phpMyAdmin! Эти сгенерированные запросы обычно включают имя базы данных, которое вам определенно не нужно, поскольку оно нарушит ваши скрипты! Что-то вроде СОЗДАТЬ ТАБЛИЦУ mydb . newtable (...) завершится ошибкой, если база данных в системе не называется mydb. Мы создали хук SVN перед комментарием, который запрещает файлы .sql, содержащие mydb строку, что является верным признаком того, что кто-то скопировал / вставил из phpMyAdmin без надлежащей проверки.

For my current PHP project we use the idea of rails migrations and we have a migrations directory in which we keep files title "migration_XX.sql" where XX is the number of the migration. Currently these files are created by hand as updates are made, but their creation could be easily modified.

Затем у нас есть сценарий под названием «Migration_watcher», который, поскольку мы находимся в предварительной альфа-версии, в настоящее время запускается при каждой загрузке страницы и проверяет, есть ли новый файл migration_XX.sql, где XX больше, чем текущая версия миграции. Если это так, он запускает все файлы migration_XX.sql до максимального числа в базе данных и вуаля! изменения схемы автоматизированы.

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

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

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

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

У К. Скотта Аллена есть приличная статья или две по управлению версиями схемы, в которых используется концепция сценариев / миграций инкрементного обновления, упоминаемая в других ответах здесь; см. http://odetocode.com/Blogs/scott/archive/2008/01/31/11710.aspx .

Я бы порекомендовал использовать Ant (кроссплатформенный) для «сценария» (поскольку он может практически взаимодействовать с любой базой данных через jdbc) и Subversion для исходного репозитория. Ant позволит вам "скопировать" вашу базу данных в локальные файлы перед внесением изменений. 1. резервное копирование существующей схемы базы данных в файл через Ant 2. контроль версий в репозиторий Subversion через Ant 3. отправка новых операторов sql в базу данных через Ant

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

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

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

Тогда у вас есть много вариантов: вы можете взять эти сценарии и поместить их в свой SVN с кодом своего приложения, чтобы он был развернут с помощью вашего существующего механизма. Другой вариант - использовать механизм доставки neXtep: сценарии экспортируются в так называемый «пакет доставки» (сценарии SQL + дескриптор XML), и установщик может понять этот пакет и развернуть его на целевом сервере, обеспечивая при этом структурную согласованность и зависимость. проверка, регистрация установленной версии и т. д.

Продукт распространяется под лицензией GPL и основан на Eclipse, поэтому он работает в Linux, Mac и Windows. На данный момент он также поддерживает Oracle, Mysql и Postgresql (поддержка DB2 уже в пути). Взгляните на вики, где вы найдете более подробную информацию: http://www.nextep-softwares.com/wiki

В Toad для MySQL есть функция, называемая сравнением схемы, которая позволяет синхронизировать 2 базы данных. Это лучший инструмент, который я когда-либо использовал.

Мне нравится, как Yii выполняет миграцию базы данных. Миграция - это в основном реализация сценария PHP CDbMigration. CDbMigration определяет up метод, содержащий логику миграции. Также возможно реализовать down метод для поддержки отмены миграции. В качестве альтернативы safeUp или safeDown можно использовать, чтобы убедиться, что миграция выполняется в контексте транзакции.

Инструмент командной строки Yii yiic поддерживает создание и выполнение миграций. Миграции могут применяться или отменяться по одному или в пакетном режиме. Создание миграции приводит к созданию кода для реализации класса PHP с CDbMigration уникальным именем, основанным на метке времени и имени миграции, указанном пользователем. Все миграции, которые ранее были применены к базе данных, хранятся в таблице миграции.

Дополнительные сведения см. В статье « Перенос базы данных» в руководстве.