Merql
Чистое PHP-стороннее слияние базы данных с разрешением конфликтов на уровне столбцов. Семантика слияния в стиле Git применяется к таблицам MySQL и SQLite.
composer require merql/merqlПоследний выпуск v0.4.1 MIT PHP 8.2+
use Merql\Merql;
Merql::init($connection);
// Snapshot all tables.
$snapshot = Merql::snapshot('baseline');
// Snapshot specific tables.
$snapshot = Merql::snapshot('baseline', ['posts', 'comments', 'users']);На практике
При слиянии считываются три сохраненных снимка и возвращаются операции для записи и конфликты для разрешения.
Объединение трех снимков
Сделайте базовый снимок до расхождения двух копий, а затем создайте снимок каждой стороны, например рабочей базы данных и ее копии в песочнице. ThreeWayMerge сравнивает обе стороны с базовой версией и объединяет два набора изменений.
На вкладке результата видно, что в одной и той же строке с нашей стороны отредактирован content, а с их стороны — title и status; слияние сохраняет все три изменения без конфликта.
use Merql\Merge\ThreeWayMerge;
$merge = new ThreeWayMerge();
$result = $merge->merge($base, $ours, $theirs);
echo $result->operationCount(); // resolved operations
echo $result->conflictCount(); // unresolved conflictsBase: { title: "Hello", content: "Body", status: "draft" }
Ours: { title: "Hello", content: "Body v2", status: "draft" }
Theirs: { title: "New Title", content: "Body", status: "publish" }
Result: { title: "New Title", content: "Body v2", status: "publish" }Трехстороннее слияние
Базовая версия, наша, их. Трехстороннее слияние в стиле git для строк с ключами и столбцов вместо строк текста. Обнаруживает добавления, обновления и удаления в двух ветках.
Разрешение конфликтов на уровне столбцов
Если обе стороны меняют одну и ту же строку, merql сравнивает ее по столбцам. Конфликт возникает, только если один и тот же столбец изменен на разные значения.
Слияние ячеек по выбору
Передайте CellMergeConfig в ThreeWayMerge, и столбцы TEXT будут объединяться построчно с помощью Myers diff, а столбцы JSON — по ключам. Фасад Merql и CLI не включают эту возможность.
Несколько баз данных
Подключаемые адаптеры соединений и драйверы диалектов; встроены MySQL и SQLite.
Обнаружение конфликтов
Обновление против обновления, обновление против удаления, удаление против обновления и добавление против добавления — каждый конфликт указывается вместе с таблицей и строкой. Для конфликтов обновления указывается также столбец.
Генерация SQL
Параметризованные операторы INSERT, UPDATE, DELETE с учетом внешних ключей при упорядочивании. Предварительный просмотр без выполнения или применение в транзакции.
CLI
Создание снимков, сравнение и слияние из командной строки. Поддерживаются MySQL и SQLite через переменные окружения.
Проверено тестами
32 регрессионных сценария с написанными вручную ожидаемыми результатами (composer test:oracle). CI выполняет модульные и интеграционные тесты 231, а также проверку уровня 10 PHPStan.
Почему Merql
Снимки — это файлы
Каждый снимок — это файл JSON, который можно копировать между компьютерами или добавлять в систему контроля версий. Сравнение и слияние читают эти файлы, поэтому для их выполнения не требуется подключение к базе данных.
Проверьте перед записью
План слияния присваивает каждой операции и группе изменений стабильный идентификатор и сохраняет строки базовой версии, нашей версии, их версии и результата. Выберите нужные группы и примените только их.
Устаревшие планы останавливаются
Защищенное применение записывает изменения только в строки, которые по-прежнему соответствуют проверенному снимку. Если оператор затрагивает ноль строк, транзакция откатывается, а в результат включается ошибка.
Откат с проверкой расхождений
Создайте план отката по строкам рабочей базы непосредственно перед записью и сохраните его как JSON. Перед отменой изменений проверка расхождений сравнивает отпечатки строк и возвращает операции для строк, изменившихся с тех пор.
Сравнение с
Merql объединяет данные строк из трех снимков. Эти инструменты управляют версиями, синхронизируют или переносят базы данных — это смежные задачи.
| Инструмент | Подходит для | Отличия от Merql |
|---|---|---|
| Dolt | Подходит дляDolt — это база данных SQL, которую можно разветвлять, клонировать, создавать в ней ветки, объединять их, отправлять и получать изменения, как в репозитории Git. К ней подключаются как к любой базе данных MySQL, и она отслеживает происхождение каждой ячейки. | Отличия от MerqlMerql сохраняет уже используемую вами базу данных MySQL или SQLite. Она сохраняет таблицы в файлах снимков JSON и объединяет три таких файла; базовый снимок выбираете вы. |
| pt-table-sync | Подходит дляpt-table-sync находит и устраняет различия между таблицами MySQL — в одном направлении или в обоих между серверами. При синхронизации реплики он вносит изменения в источник репликации. | Отличия от MerqlПри двусторонней синхронизации pt-table-sync выбирает итоговую строку по столбцу конфликта и копирует ее значения. Merql сравнивает обе стороны с общей базовой версией, объединяет изменения разных столбцов одной строки и сообщает о несовместимых изменениях как о конфликтах, которые нужно разрешить. |
| sqldiff | Подходит дляsqldiff сравнивает две базы данных SQLite и выводит скрипт SQL, который преобразует первую во вторую. Также он может записать двоичный набор изменений для расширения сессии SQLite или составить сводку измененных строк по таблицам. | Отличия от MerqlПри двустороннем сравнении нельзя определить, добавлена ли строка на одной стороне или удалена на другой. Merql использует базовый снимок, чтобы выяснить это, объединяет два набора изменений и работает также с MySQL. |
| Doctrine Migrations | Подходит дляDoctrine Migrations ведет версии схемы базы данных, чтобы изменения схемы можно было проверять и тестировать до развертывания в рабочей среде. | Отличия от MerqlMerql не является инструментом миграции схем. Он объединяет данные строк и сообщает о столбцах, добавленных или удаленных между снимками, а изменение схемы остается вашей задачей. |
Источники, отмечено
Вопросы и ответы
Краткие ответы из документации Merql.
MySQL и SQLite — через адаптеры PDO или mysqli. Для другого движка создайте класс, реализующий интерфейс Driver, и зарегистрируйте его с помощью DriverFactory::register().
Нет. Он не переносит схемы, не реплицирует базы данных и не синхронизирует их в реальном времени. Получив три состояния базы данных, он создает четвертое, объединенное, и указывает конфликты.
Когда обе стороны изменяют один и тот же столбец одной и той же строки на разные значения, когда одна сторона обновляет строку, удаленную другой, или когда обе добавляют строку с одинаковым ключом. Изменения разных столбцов одной строки объединяются без конфликтов.
Нет. Они читают сохраненные файлы снимков, поэтому подключение к базе данных требуется только для создания снимка и применения результата.
Да. Создайте план слияния, выберите группы изменений по их идентификаторам и преобразуйте выбор в результат без конфликтов для Merql::apply() или Merql::applyGuarded().
Только если включить эту возможность, создав ThreeWayMerge с CellMergeConfig, например CellMergeConfig::auto(). Merql::merge(), Merql::plan() и CLI рассматривают значение каждого столбца целиком.
Следуйте руководству: от первого снимка до планов слияния, защищенного применения и отката.