Ugrás a tartalomhoz

SQL tükör

Az SqlMirror a storh gyűjteményeket az SQLite vagy az MySQL tábláiba tölti, így egyesítéseket, táblák közötti rendezést, részszöveges keresést és jelentéseket futtathat az SQL rendszerben, miközben a fájlok maradnak a hiteles adatforrások. Tekintsen rá úgy, mint egy másodlagos indexre, amely történetesen adatbázis: a tükör származtatott, eldobható, és bármikor újraépíthető. Az sqlite vagy mysql illesztőprogrammal használt ext-pdo csak akkor szükséges, ha használja; az alapcsomagnak nincs függősége.

Beállítás

PHP
use Storh\DocStore;
use Storh\Schema;
use Storh\SqlMirror;

$schema = Schema::collection('pages')
    ->string('slug')->unique()
    ->string('kind')->index()
    ->int('publishedAt')->range();

$pages  = new DocStore($root, 'pages', schema: $schema);
$events = new Storh\SegmentedLog($root, 'events');

$mirror = new SqlMirror(new PDO('sqlite:' . $root . '/mirror.db'), 'app_');
$mirror->collection($pages, 'pages', $schema);
$mirror->collection($events, 'events');

$mirror->install();
$mirror->push();

Mindkét motor tükrözhető: a DocStore gyűjtemények és az SegmentedLog adatfolyamok (csak az aktív rekordok kerülnek át). A Schema megadása nem kötelező, és független az adattártól: a deklarált string/int/float/bool mezők típusos, indexelt oszlopokká válnak; minden más továbbra is lekérdezhető a data JSON oszlopban. A mixed mezők nem jelölhetők indexelésre.

Kapcsolatok

A konstruktor PDO kezelőt (automatikusan felismeri az sqlite vagy mysql illesztőprogramot), mysqli kezelőt vagy bármely SqlMirrorConnection implementációt fogad el:

PHP
$mirror = new SqlMirror(new PDO('sqlite:' . $root . '/mirror.db'));
$mirror = new SqlMirror(new PDO('mysql:host=127.0.0.1;dbname=app;charset=utf8mb4', $user, $password));
$mirror = new SqlMirror(new mysqli('127.0.0.1', $user, $password, 'app'), 'wp_storh_');

A mysqli útvonal mindkét mysqli hibajelentési móddal működik, így egy gazdaalkalmazás meglévő kezelője (például az WordPress $wpdb->dbh kezelője) változtatás nélkül újra felhasználható. A viselkedés azonos az illesztőprogramok között; a sikertelen feltöltések mindegyiknél visszagörgetik a gyűjtemény tranzakcióját.

Minden tábla megkapja az id mezőt (elsődleges kulcs), az hash mezőt (ez vezérli a növekményes feltöltéseket), a típusos oszlopokat, valamint az data mezőt (a teljes rekord JSON formában).

Szinkronizálás

PHP
$mirror->push();                    // reconcile: insert, update, delete as needed
$mirror->push('pages');             // reconcile a single collection
$mirror->flush('pages', $ids);      // push or remove just these ids
$mirror->pull();                    // write mirror rows back into the store
$mirror->verify();                  // report missing, stale, and orphaned rows
$mirror->rebuild();                 // clear all rows and push from scratch
$mirror->uninstall();               // drop the mirror tables

Az push() összeveti a rekordkivonatokat a tükörrel, és minden gyűjteményt egyetlen tranzakcióban ír ki, ezért egy összeomlott vagy sikertelen feltöltés sem hagy félkész köteget maga után. A változatlan rekordok egyetlen SELECT műveletet és egy rekordbejárást igényelnek. Egy rendszeres push() (például egy cron ütemezett futtatás) fenntartja a tükör szinkronját; hívja meg az flush() függvényt az adott kérésben írt azonosítókkal, ha az olvasóknak azonnal látniuk kell a tükörben a saját írásaikat.

Lekérdezés

A tükröt egyszerű SQL használatával kérdezze le. Az table() adja vissza a tükrözött tábla nevét:

PHP
$pdo->query(
    'SELECT p.slug, COUNT(*) AS sales
     FROM ' . $mirror->table('purchases') . ' o
     INNER JOIN ' . $mirror->table('products') . ' p ON p.id = o.product_id
     GROUP BY p.slug
     ORDER BY sales DESC'
);

Visszatöltés fájlokba

Az pull() beolvassa a tükör sorait, majd azonosító szerinti sorrendben beírja őket a regisztrált adattárba. Két munkafolyamatot támogat:

  • Visszaállítás: a fájlok elvesztek, de a tükör megmaradt. Regisztráljon egy új adattárat ugyanazzal a gyűjteménynévvel, majd végezze el a visszatöltést.
  • Feltöltés: külső eszközök által a tükörtáblába betöltött sorokból storh rekordok lesznek. A soroknak érvényes UUIDv7 azonosítókat és egy objektumot kell tartalmazniuk az data oszlopban; a típusos oszlopokat a visszatöltés figyelmen kívül hagyja, mert a teljes rekordot az data tartalmazza.
PHP
$restored = new Storh\DocStore($root, 'pages');
$mirror   = new SqlMirror($pdo);
$mirror->collection($restored, 'pages');
$mirror->pull();          // ['written' => n, 'unchanged' => m]

A visszatöltött írások a szokásos adattárt használják, így érvényesül a sémaellenőrzés és az egyedi indexelés, minden rekord pedig tartósan kiíródik. Az pull() soha nem töröl helyi rekordokat, és kihagyja azokat, amelyek adatai már megegyeznek a tükör soraival. A kézzel beszúrt sorok feltöltése után futtassa le egyszer az push() műveletet: ez kanonikus formában írja újra a sorokat, hogy a kivonataik egyezzenek.

Szerződés és korlátok

  • A fájlok a hiteles adatforrások. A tükör csak olvasható kimenet; a kézzel beleírt adatokat a következő push() felülírja vagy törli.
  • A tükör egyedi oszlopai védelmi hálót jelentenek, nem íráskori ellenőrzést: a fájlok által megengedett ismétlődés sikertelen (és teljesen visszagörgetett) feltöltést eredményez. Az íráskori ellenőrzéshez használjon storh egyedi indexeket.
  • A tükör a fájlokhoz képest akár egy feltöltési időközzel is lemaradhat, kivéve azokat az azonosítókat, amelyeket kifejezetten megad az flush() függvénynek.
  • A tükrözés önmagában nem ad tranzakciókat az storh rendszerhez. A több rekordot érintő atomi írások továbbra is egy valódi adatbázis feladatai, amely a rendszer hiteles adatforrásaként szolgál.
  • A sémamódosítások a tükör eldobásával és újratelepítésével alkalmazhatók: uninstall(), install(), push().