Перенос изменений базы данных из
Возможно, самый большой риск в реализации новой функциональности связан с модификациями базы данных, необходимыми для нового кода. Я считаю, что в Rails у них есть "миграции", в которых вы можете программно вносить изменения в хост разработки, а затем вносить те же изменения в живую вместе с кодом, использующим пересмотренную схему. И при необходимости откатите оба спины синхронизированным способом.
Кто-нибудь сталкивался с подобным набором инструментов для PHP/MySQL? Хотелось бы услышать об этом или о любых программных или процессных решениях, которые помогут сделать это менее рискованным...
Ответы
Ответ 1
Я никогда не сталкивался с инструментом, который бы выполнял эту работу. Вместо этого я использовал отдельные файлы, пронумерованные так, чтобы я знал, какой порядок их запуска: по существу, ручная версия миграции Rails, но без отката.
Вот что я говорю о:
000-clean.sql # wipe out everything in the DB
001-schema.sql # create the initial DB objects
002-fk.sql # apply referential integrity (simple if kept separate)
003-reference-pop.sql # populate reference data
004-release-pop.sql # populate release data
005-add-new-table.sql # modification
006-rename-table.sql # another modification...
Я никогда не сталкивался с такими проблемами, но это не очень элегантно. Это зависит от вас, чтобы отслеживать, какие сценарии должны запускаться для данного обновления (может помочь более разумная схема нумерации). Он также отлично работает с контролем источника.
Работа с суррогатными значениями ключа (из столбцов автонабора) может быть больной, поскольку у базы данных производства, вероятно, будут разные значения, чем БД разработки. Поэтому я стараюсь никогда не ссылаться на буквальное суррогатное значение ключа в любом из моих скриптов модификации, если это вообще возможно.
Ответ 2
Я не доверяю программным переходам. Если это простое изменение, например, добавление столбца NULLable, я просто добавлю его непосредственно на живой сервер. Если это сложнее или требует изменения данных, я напишу пару файлов миграции SQL и протестирую их в базе данных реплик.
При использовании миграции всегда проверяйте миграцию отката. Это ваша аварийная кнопка "oh shit".
Ответ 3
Я использовал этот инструмент раньше, и он отлично работал.
http://www.mysqldiff.org/
В качестве входа используется либо соединение с БД, либо файл SQL, и сравнивает его с тем же (либо другое соединение с БД, либо другой файл SQL). Он может выплевывать SQL для внесения изменений или внесения изменений для вас.
Ответ 4
@[yukondude]
Я сам использую Perl, и я прошел путь маршрутизации в стиле Rails полу-вручную таким же образом.
То, что у меня было, это одна "версия" таблицы с одной колонкой "версия", содержащая одну строку одного номера, которая является текущей версией схемы. Тогда было (довольно) тривиально написать script, чтобы прочитать это число, посмотреть в определенном каталоге и применить все пронумерованные миграции, чтобы добраться оттуда туда (и затем обновить номер).
В моей среде dev/stage я часто (через другой script) извлекаю производственные данные в промежуточную базу данных и запускаю миграцию script. Если вы сделаете это, прежде чем вы начнете жить, вы будете уверены, что миграция будет работать. Очевидно, что вы много тестируете в своей промежуточной среде.
Я помещаю новый код и требуемые миграции под одним тегом управления версиями. Для развертывания на сцене или вживую вы просто обновляете все до этого тега и выполняете миграцию script довольно быстро. (Возможно, вы захотели бы организовать короткий простоя, если это действительно изменяет схему.)
Ответ 5
Решение, которое я использую (изначально разработанным моим другом), является другим дополнением к юкондуде.
- Создайте каталог схемы под управлением версии, а затем для каждого изменения db вы создадите файл .sql с SQL, который вы хотите выполнить вместе с SQL-запросом, для обновления таблицы db_schema.
- Создайте таблицу базы данных под названием "db_schema" с целым столбцом с именем version.
- В каталоге схемы создайте два сценария оболочки, "текущий" и "обновление". Выполнение текущего сообщения указывает, к какой версии схемы db подключена база данных, к которой вы подключены. Запуск обновления выполняет каждый файл .sql, пронумерованный больше, чем версия в таблице db_schema, последовательно до тех пор, пока вы не достигнете наибольшего нумерованного файла в директории схемы.
Файлы в директории схемы:
0-init.sql
1-add-name-to-user.sql
2-add-bio.sql
Как выглядит типичный файл, обратите внимание на обновление db_schema в конце каждого файла .sql:
BEGIN;
-- comment about what this is doing
ALTER TABLE user ADD COLUMN bio text NULL;
UPDATE db_schema SET version = 2;
COMMIT;
"current" script (для psql):
#!/bin/sh
VERSION=`psql -q -t <<EOF
\set ON_ERROR_STOP on
SELECT version FROM db_schema;
EOF
`
[ $? -eq 0 ] && {
echo $VERSION
exit 0
}
echo 0
обновление script (также psql):
#!/bin/sh
CURRENT=`./current`
LATEST=`ls -vr *.sql |egrep -o "^[0-9]+" |head -n1`
echo current is $CURRENT
echo latest is $LATEST
[[ $CURRENT -gt $LATEST ]] && {
echo That seems to be a problem.
exit 1
}
[[ $CURRENT -eq $LATEST ]] && exit 0
#SCRIPT_SET="-q"
SCRIPT_SET=""
for (( I = $CURRENT + 1 ; I <= $LATEST ; I++ )); do
SCRIPT=`ls $I-*.sql |head -n1`
echo "Adding '$SCRIPT'"
SCRIPT_SET="$SCRIPT_SET $SCRIPT"
done
echo "Applying updates..."
echo $SCRIPT_SET
for S in $SCRIPT_SET ; do
psql -v ON_ERROR_STOP=TRUE -f $S || {
echo FAIL
exit 1
}
done
echo OK
My 0-init.sql имеет полную начальную структуру схемы вместе с начальным "UPDATE db_schema SET version = 0;". Не должно быть слишком сложно изменить эти сценарии для MySQL. В моем случае у меня также есть
export PGDATABASE="dbname"
export PGUSER="mike"
в моем .bashrc. И он запрашивает пароль с каждым исполняемым файлом.
Ответ 6
У Symfony есть плагин под названием sfMigrationsLight, который обрабатывает основные миграции. CakePHP также имеет миграции.
По какой-то причине поддержка миграции никогда не была высокоприоритетной для большинства фреймворков PHP и ORM.
Ответ 7
Я использую SQLyog, чтобы скопировать структуру, и я ВСЕГДА, позвольте мне повторить ВСЕГДА сделать резервную копию первой.
Ответ 8
Довольно многое описано в описании Lot105.
Каждая миграция требует применения и отката script, и у вас есть какой-то элемент управления script, который проверяет, какие миграции необходимо применять, и применяет их в соответствующем порядке.
Каждый разработчик сохраняет свои db в синхронизации, используя эту схему, и при применении к производству применяются соответствующие изменения. Сценарии отката могут быть сохранены, чтобы отменить изменение, если это становится необходимым.
Некоторые изменения не могут быть выполнены с помощью простого ALTER script, такого как инструмент, например sqldiff; некоторые изменения не требуют изменения схемы, а программные изменения существующих данных. Таким образом, вы не можете действительно обобщить, поэтому вам нужен человеко-отредактированный script.
Ответ 9
Я всегда предпочитал, чтобы мой сайт разработки указывал на тот же БД, что и на сайте. Сначала это может показаться рискованным, но на самом деле оно решает многие проблемы. Если у вас есть два сайта на одном сервере, указывающие на один и тот же БД, вы получаете точное и точное представление о том, что ваши пользователи будут видеть, когда он будет жить.
У вас будет только одна база данных и до тех пор, пока вы сделаете ее политикой, чтобы никогда не удалять столбец из таблицы, вы знаете, что ваш новый код будет соответствовать вашей базе данных.
При миграции также значительно меньше хаоса. Вам нужно только переместить скрипты PHP, и они уже протестированы с использованием того же БД.
Я также создаю символическую ссылку для любой папки, которая является целью для загрузки пользователей. Это означает, что нет путаницы в том, какие пользовательские файлы были обновлены.
Другим побочным эффектом является возможность портирования небольшой группы "бета-тестеров" для использования сайта в повседневном использовании. Это может привести к большому количеству отзывов, которые вы можете реализовать перед публичным запуском.
Это может не работать во всех случаях, но я начал перемещать все мои обновления в эту модель. Это вызвало гораздо более плавное развитие и запуск.
Ответ 10
В прошлом я использовал LiquiBase, инструмент на основе Java, в котором вы настраиваете свои миграции как файлы XML. Вы можете сгенерировать необходимый SQL с ним.
Сегодня я бы использовал библиотеку Doctrine 2, в которой объекты миграции аналогично Ruby.
Структура Symfony 2 также имеет хороший способ справиться с изменениями схемы - ее инструмент командной строки может анализировать существующую схему и генерировать SQL для сопоставить базу данных с измененными определениями схемы.