Управление исходным кодом схемы MySQL - PullRequest
4 голосов
/ 01 июня 2011

В моей компании есть несколько разработчиков, каждый из которых работает над проектами внутри компании, каждый со своей настройкой виртуальной коробки.Мы используем SVN для обработки исходного кода, но иногда сталкиваемся с проблемами, когда необходимо изменить схему базы данных (MySQL), и это необходимо распространить на всех остальных разработчиков.На данный момент у нас есть записанный вручную файл журнала, в котором перечислены изменения и SQL, необходимые для выполнения изменения.

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

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

Ответы [ 4 ]

2 голосов
/ 01 июня 2011

Есть пара подходов, которые я использовал ранее или использую в настоящее время:

Номер последовательной версии

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

Таким образом, если версия 37 и в приложении для обновления есть операторы, связанные с версиями 1–38, она пропустит 1–37 и выполнит операторы, чтобы привести базу данных к версии 38.

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

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

Направленный ациклический граф

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

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

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

Я выбрал этот подход, потому что проект часто имеет параллельную разработку несколькими разработчиками, причем каждый разработчик иногда имеет более чем одну вещь в разработке (ветвистая разработка, иногда очень ветвь). Жонглирование номерами баз данных было довольно болезненно. Если все начали с версии 37, и «Алиса» что-то запускает и использует версию 38, поэтому она изменит свою базу данных, и «Боб» также начнет работу, которая должна изменить базу данных, а также использует версию 38, кому-то потребуется в конечном итоге изменить , Допустим, Боб заканчивает работу и отправляет на сервер. Теперь Алиса, когда она извлекает ревизию Боба, должна изменить версию для операторов на 39 и установить версию своей базы данных обратно на 37, чтобы изменения Боба были выполнены, но затем она выполняет снова .

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

Мы используем Mercurial (распределенный), а не SVN (клиент-сервер), поэтому у нас такой подход работает так хорошо.

2 голосов
/ 01 июня 2011

Я бы рассмотрел что-то вроде MyBatis Schema Migration tools .Это не совсем то, что вы описываете, но я думаю, что это решает вашу проблему элегантным способом и может быть использовано без использования ядра MyBatis.

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

Таким образом, у вас будет такая схема:

-- Version: 1
CREATE TABLE user (
id bigint,
name varchar(20))

У вас есть инструмент для управления таблицей версий схемы и вы увидите что-то вроде:

> SELECT * FROM schema_version;
1,2011-05-05

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

-- Version: 2
ALTER TABLE user ADD email varchar(20);
-- Version: 3
ALTER TABLE user ADD phone varchar(20);

И соответствующая новая схема будет проверена с помощью:

-- Version: 3
CREATE TABLE user (
id bigint,
name varchar(20),
email charchar(20),
phone varchar(20))

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

2 голосов
/ 01 июня 2011

Один из вариантов - это словарь данных в YAML / JSON.Есть хорошая статья здесь

1 голос
/ 01 июня 2011

Простым решением было бы сохранить полную схему в SVN (или любой другой библиотеке). То есть, каждый раз, когда вы меняете схему, запускайте MySQL "desc", чтобы вывести описания всех таблиц, переписать последний такой дамп схемы с этим, а затем зафиксировать. Затем, если вы запустите версию diff, она должна сообщить вам, что изменилось. Вам, конечно же, нужно хранить все таблицы в алфавитном порядке (или в некотором предсказуемом порядке).

Для другого подхода: Несколько лет назад я работал над проектом для настольного приложения, в котором мы периодически рассылали новые версии, которые могли иметь изменения схемы, и мы хотели обрабатывать их без вмешательства пользователя. Таким образом, у программы было описание того, какую схему она ожидала. При запуске он сделал несколько вызовов метаданных, чтобы проверить схему базы данных, которая у нее была на самом деле, и сравнить их с тем, что он ожидал. Если затем автоматически обновляется схема, чтобы соответствовать тому, что ожидалось. Обычно, когда мы добавляли новый столбец, мы могли просто позволить ему начинать с нуля или пустым, так что это потребовало практически нулевого усилия по написанию кода, как только мы заработали первую версию. Когда для заполнения новых полей требовались какие-то фактические манипуляции, нам приходилось писать собственный код, но это было относительно редко.

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