Uvod
merql je čista knjižnica PHP za trosmerno združevanje stanj podatkovne zbirke. Ustvari posnetke tabel, izračuna nabore sprememb med posnetki, združi dva nabora sprememb glede na skupno osnovo in zazna spore na ravni stolpcev. Uporablja isti algoritem kot git za izvorne datoteke, le da namesto vrstic obdeluje zapise in stolpce.
Brez zunanjih orodij. Podpira MySQL in SQLite prek prilagodljivih povezovalnih adapterjev in gonilnikov za dialekte.
Kratek primer
Za združitev potrebujete tri stanja istih podatkov: osnovo, iz katere sta izšli obe kopiji, in obe kopiji po njunih neodvisnih spremembah. Tukaj je bilo testno okolje kopirano iz produkcijske podatkovne zbirke, od takrat pa sta bili obe spremenjeni.
use Merql\Connection;
use Merql\Merql;
$live = Connection::sqlite('/data/live.sqlite');
$sandbox = Connection::sqlite('/data/sandbox.sqlite');
// Base: live at the moment the sandbox was copied from it.
Merql::init($live);
Merql::snapshot('base');
// ... copy live.sqlite to sandbox.sqlite, then both databases change ...
// Ours: the sandbox with our edits. Theirs: live with its own changes.
Merql::init($sandbox);
Merql::snapshot('ours');
Merql::init($live);
Merql::snapshot('theirs');
$result = Merql::merge('base', 'ours', 'theirs');
if ($result->isClean()) {
foreach ($result->operations() as $operation) {
echo "{$operation->type} {$operation->table} #{$operation->rowKey} ({$operation->source})\n";
}
} else {
echo "Conflicts: {$result->conflictCount()}\n";
}
Vsak posnetek se ustvari iz podatkovne zbirke, ki vsebuje to stanje. Če vse tri posnetke zaporedoma ustvarite v eni podatkovni zbirki, ne dobite dveh razšlih se kopij: njihova kopija bi že vsebovala naše spremembe, vsaka vrstica, ki smo jo dodali, pa bi bila označena kot spor insert_insert.
Rezultat navede operacije z obeh strani, ki osnovo pretvorijo v združeno stanje, pri čemer je vsaka označena s svojim virom (ours, theirs ali merged). Če želite spremembe iz testnega okolja zapisati v produkcijsko okolje, z orodjem Zaščitena uporaba uveljavite operacije, ki jih v produkcijskem okolju še ni.
Ali iz CLI, ki se poveže s podatkovno zbirko, navedeno v MERQL_DB_DSN za vsak snapshot:
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot base
# ... copy live.sqlite to sandbox.sqlite, then both databases change ...
MERQL_DB_DSN="sqlite:/data/sandbox.sqlite" vendor/bin/merql snapshot ours
MERQL_DB_DSN="sqlite:/data/live.sqlite" vendor/bin/merql snapshot theirs
vendor/bin/merql merge base ours theirs --dry-run
Zakaj merql
Večina orodij za primerjavo stanj podatkovnih zbirk deluje na ravni vrstic: če se med dvema različicama razlikuje kateri koli stolpec v vrstici, je celotna vrstica označena kot spor. To povzroči lažne spore, kadar dve osebi urejata različna stolpca iste vrstice.
merql združuje na ravni stolpcev. Če je ena stran spremenila title, druga pa status, se spremembe združijo brez spora. Spor nastane le, če obe strani spremenita isti stolpec na različni vrednosti.
Za stolpca TEXT in JSON lahko merql združevanje poglobi na raven celic. Dve spremembi različnih vrstic v besedilnem stolpcu ali različnih ključev stolpca JSON se lahko brez težav združita z istim trosmernim algoritmom. Združevanje na ravni celic je izbirno: posredujte CellMergeConfig v ThreeWayMerge. Vmesnik Merql in CLI združujeta samo na ravni stolpcev. Glejte Združevanje na ravni celic.
Model združevanja
Base (snapshot at fork time)
/ \
Ours (one copy's changes) Theirs (the other copy's changes)
\ /
--------- MERGE ----------
|
Merged result
+ conflicts (if any)
Tri stanja, enako kot pri git. Osnova je skupni prednik. Naši in njihovi podatki sta kopiji po razhajanju, vsaka zajeta iz svoje podatkovne zbirke. Pravila združevanja obe strani obravnavajo enako. Imena se pojavijo v source vsake operacije, pri vrstah sporov (update_delete pomeni, da smo mi posodobili, oni pa izbrisali) ter v pravilih razreševanja OursWins in TheirsWins. Brez skupne osnove ni mogoče razlikovati med »dodano« in »nespremenjeno«.
Združitev sama po sebi ničesar ne zapiše. Njene operacije pretvorijo osnovo v združeno stanje, zato jih Merql::apply() uspešno izvede samo v podatkovni zbirki, ki še vedno vsebuje osnovo. Če želite spremembe ene strani prenesti v podatkovno zbirko, ki že vsebuje spremembe druge strani, na primer spremembe iz testnega okolja v produkcijsko, uveljavite samo operacije, ki ji manjkajo; glejte Zaščitena uporaba.
Zahteve
- PHP 8.2 ali novejša različica.
ext-mbstringinext-zlib, ki ju zahteva odvisnostpitmaster/pitmasterza prikaz razlik v besedilu.- Razširitev podatkovne zbirke za adapter, ki ga uporabljate:
ext-pdozext-pdo_sqlitealiext-pdo_mysqloziromaext-mysqli. Konfiguracijacomposer.jsonza merql predlaga samoext-pdoinext-mysqli, zato jih Composer ne preverja. - Podatkovna zbirka MySQL ali SQLite. Za druge pogone potrebujete prilagojen gonilnik.
Kaj ni
merql ni orodje za selitev shem. Ne podvaja podatkovnih zbirk in jih ne sinhronizira v realnem času. Rešuje eno samo težavo: iz treh stanj podatkovne zbirke ustvari četrto, združeno stanje, in označi spore.
Dokumentacija
- Uvod -- namestitev, prvi posnetek, prva združitev.
- CLI Referenca -- celotna referenca za ukaz
vendor/bin/merql. - PHP API Referenca -- popolna dokumentacija API za vse razrede.
- Načrti združevanja -- stabilni ID-ji operacij, skupine sprememb in izbori.
- Zaščitena uporaba -- izbrani zapisi s predpogoji za aktivne vrstice.
- Povrnitev -- artefakti za povrnitev in preverjanje odstopanj.