Перенос изменений базы данных из разработки в живую

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

Кто-нибудь сталкивался с подобным набором инструментов для PHP / MySQL? Хотел бы услышать об этом или о любых программных или технологических решениях, которые помогут сделать это менее рискованным ...

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
14
0
3 581
10

Ответы 10

В Symfony есть плагин sfMigrationsLight, который обрабатывает базовые миграции. CakePHP также имеет миграции.

По какой-то причине поддержка миграции никогда не была приоритетной для большинства PHP-фреймворков и ORM.

Я никогда не встречал инструмента, который бы справился с этой задачей. Вместо этого я использовал отдельные файлы, пронумерованные, чтобы я знал, в каком порядке их запускать: по сути, это ручная версия миграции 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...

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

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

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

При использовании миграций всегда тестирует откат миграции. Это твоя аварийная кнопка «черт возьми».

Я использую SQLyog для копирования структуры, и я ВСЕГДА, позвольте мне повторять, ВСЕГДА сначала делайте резервную копию.

Я использовал этот инструмент раньше, и он отлично работал.

http://www.mysqldiff.org/

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

@ [yukondude]

Я сам использую Perl, и таким же образом я прошел путь миграции в стиле Rails наполовину вручную.

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

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

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

Примерно то, что описал Lot105.

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

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

Некоторые изменения невозможно выполнить с помощью простого сценария ALTER, такого как такой инструмент, как sqldiff; некоторые изменения требуют не изменения схемы, а программного изменения существующих данных. Таким образом, вы не можете действительно обобщать, поэтому вам нужен сценарий, редактируемый человеком.

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

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

При миграции также значительно меньше хаоса. Вам нужно только перейти к сценариям PHP, и они уже протестированы с использованием той же БД.

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

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

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

Как вы справляетесь с переименованием столбцов? Быстрое переименование сломает вашу производственную среду, верно?

Kevin Pang 01.07.2009 06:57

@Kevin Pang - это правда, но я не слишком часто переименовываю свои столбцы. Я обнаружил, что меньший демон - оставить имена столбцов такими, какие они есть. Это заставляет меня тщательно обдумывать названия столбцов, но я также считаю, что это редкое явление. Если переименование должно произойти, поиск-замена в двух системах не займет больше времени, чем в одной системе. Это по-прежнему вызывает меньше простоев и неудобств, чем миграция БД. Я знаю, что это нестандартно, но мне это очень нравится :)

Paulo 01.07.2009 07:13

Решение, которое я использую (изначально разработанное моим другом), является еще одним дополнением к yukondude.

  1. Создайте каталог схемы под контролем версий, а затем для каждого изменения базы данных, которое вы делаете, сохраняйте файл .sql с SQL, который вы хотите выполнить, вместе с запросом sql для обновления таблицы db_schema.
  2. Создайте таблицу базы данных с именем «db_schema» с целочисленным столбцом с именем version.
  3. В каталоге схемы создайте два сценария оболочки: «текущий» и «обновленный». Выполнение current сообщает вам, в какой версии схемы 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;

«Текущий» скрипт (для 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

скрипт обновления (также 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

Мой 0-init.sql имеет полную структуру начальной схемы вместе с исходной «UPDATE db_schema SET version = 0;». Изменить эти сценарии для MySQL не составит большого труда. В моем случае у меня тоже есть

export PGDATABASE = "dbname"
export PGUSER = "mike"

в моем .bashrc. И он запрашивает пароль для каждого исполняемого файла.

Раньше я использовал LiquiBase, инструмент на основе Java, в котором вы настраиваете свои миграции как файлы XML. С его помощью вы можете сгенерировать необходимый SQL.

Сегодня я бы использовал библиотеку Доктрина 2, которая имеет объекты миграции, похожую на Ruby.

Платформа Symfony 2 также имеет хороший способ справиться с изменениями схемы - ее инструмент командной строки может анализировать существующую схему и генерировать SQL для сопоставления базы данных с измененными определениями схемы.

Другие вопросы по теме