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
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:
$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
$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:
$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
dataoszlopban; a típusos oszlopokat a visszatöltés figyelmen kívül hagyja, mert a teljes rekordot azdatatartalmazza.
$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().