Storh
Zapisi, ki najprej uporabljajo datoteke, za PHP: dokumenti JSONC, dnevniki z dodajanjem in segmentiranjem ter čakalne vrste, podprte z dnevniki, z ID-ji UUIDv7.
composer require storh/storhNajnovejša izdaja v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();V praksi
Hiter začetek v dveh delih: dokument v korenu shrambe, nato dnevniški vnos in opravilo čakalne vrste poleg njega.
En koren, trije pogoni
StorageRoot::resolve() normalizira osnovni imenik in imenski prostor v korensko pot, vsak pogon pa ob prvi uporabi v njej ustvari svoj imenik.
Vsak pogon vrne objekte StorageRecord z id() in data(). Čakalna vrsta vsako prevzemanje in dokončanje doda v dnevnik dogodkov.
use Storh\DocStore;
use Storh\Queue;
use Storh\RecordQuery;
use Storh\SegmentedLog;
use Storh\StorageRoot;
$root = StorageRoot::resolve(__DIR__ . '/var/storh', 'demo');
$docs = new DocStore($root, 'pages');
$home = $docs->put([
'kind' => 'page',
'title' => 'Home',
]);
$loaded = $docs->get($home->id());$log = new SegmentedLog($root, 'events');
$log->put([
'type' => 'page.saved',
'pageId' => $home->id(),
]);
foreach ($log->stream(RecordQuery::all()->after($home->id())->limit(50)) as $record) {
// Process records lazily.
}
$queue = new Queue($root, 'jobs');
$jobId = $queue->enqueue(['task' => 'render', 'pageId' => $home->id()]);
$job = $queue->claim();
if (null !== $job) {
$queue->complete($job->id());
}Shramba dokumentov JSONC
Ena datoteka JSONC na zapis, ID-ji UUIDv7, razdeljevanje po dveh znakih iz zadnje skupine ID-ja UUID, atomska zamenjava in pretočni filtri polj.
Segmentirani dnevnik
Samo dodajalni segmenti vrstic JSON s predpono dolžine in kontrolne vsote, redki indeksi, branja po kazalcu in časovnem razponu, obnovitev po sesutju ter zgoščevanje.
Dnevniška čakalna vrsta
Opravila prehajajo skozi stanja čakajoče, v obdelavi in dokončano z uporabo kompaktnih samo dodajalnih dogodkov čakalne vrste.
Zapisi UUIDv7
Razvrstljivi časovno določljivi ID-ji za stabilne kazalce, omejene preglede in poti shrambe, primerne za razdelitev na drobce.
Atomski zapisi
Zapisovanje v začasne datoteke in atomsko preimenovanje ohranjata zapise v celoti. Po sesutju zapisovalnika naslednje odprtje odstrani osirotele začasne datoteke.
Obnovitev po nepopolnem zapisu
Branje segmentov preverja polja dolžine in kontrolne vsote; obnova skrajša delne zaključne vrstice.
Najprej datoteke
Brez strežnika zbirke podatkov, brez prilagodilnika ogrodja, brez izvajalnih paketov Composer; klicatelji podajo imenik.
Branje JSONC
Datoteke zapisov lahko vsebujejo komentarje in zaključne vejice. Zapisovanje storh ustvari kompaktni enovrstični JSON, zato komentarji ostanejo do naslednjega zapisa.
Gradnik poizvedb
Verižne poizvedbe, kot je where('status')->in([...]), so na voljo v DocStore in SegmentedLog; DocStore uporablja sekundarne indekse, kjer so na voljo.
Sekundarni indeksi
Indeksi enakosti, unikatnosti in obsegov so shranjeni kot datoteke ob zbirki, izpeljani iz zapisov in jih je mogoče kadar koli znova zgraditi.
Sheme
Izbirne sheme zbirk preverijo vsak zapis in določijo, katera polja se indeksirajo.
SQL zrcalo
Potisnite zbirke v SQLite ali MySQL za združevanje, iskanje in poročanje, medtem ko datoteke ostanejo kanonične. Ob uporabi potrebuje le ext-pdo ali ext-mysqli.
Zakaj Storh
Imenik, ne strežnik
Podate osnovni imenik, storh pa zapisuje vanj. Potrebuje PHP 8.2 in ext-json, brez izvajalnih paketov Composer in brez prilagodilnika ogrodja.
Enaka oblika zapisa, tri postavitve
Dokumenti, dnevniki in čakalne vrste shranjujejo ID UUIDv7 ter podatkovno polje. Postavitev na disku izberite glede na obremenitev, vse tri pa hranite pod enim korenom.
Preverjanja, ki jih lahko zaženete
verify() preveri indekse in stanje dnevnika s popolnim pregledom datotek. repair() postavi poškodovane zapise v karanteno in skrajša nepopolne konce dnevnika, CLI pa izpiše JSON za opravila cron in preverjanja stanja.
Primerjalna merila z opisom nastavitve
README objavlja mediane za 50,000 zapisov na pogon v okolju Apple M1 Pro z PHP 8.5, na primer 5.6 µs na točkovno branje. Vsi zapisi v teh meritvah so sinhronizirani z diskom, zato so hitrosti zapisovanja odvisne od datotečnega sistema.
V primerjavi z
storh je shramba, ki temelji na datotekah, in ne relacijski pogon za poizvedbe, zato ta orodja opravljajo nekatera opravila, ki jih ta ne pokriva.
| Orodje | Primerno za | Razlika v primerjavi z Storh |
|---|---|---|
| SQLite | Primerno zaSamostojen pogon SQL v eni datoteki s serializabilnimi transakcijami ACID, ki zdržijo sesutje programa ali izpad elektrike. Njegova dokumentacija ga predstavlja kot nadomestilo za priložnostne podatkovne datoteke. | Razlika v primerjavi z Storhstorh hrani po eno datoteko JSON za vsak zapis, jedro pa ne potrebuje gonilnika PDO. Nima transakcij z več zapisi; dokumentacija za takšno delo priporoča pravo zbirko podatkov. Zbirke lahko potisne v SQLite za združevanje in poročanje, datoteke pa ostanejo kanonične. |
| MySQL | Primerno zaRelacijska zbirka podatkov, ki jo streže večnitni strežnik SQL, z odjemalskimi programi in knjižnicami, skrbniškimi orodji ter širokim naborom API-jev. | Razlika v primerjavi z Storhstorh deluje znotraj procesa PHP nad imenikom, zato ni treba upravljati strežnika. Za združevanje, iskanje in poročanje zrcali zbirke v MySQL, tudi prek obstoječega ročaja mysqli, datoteke pa ostanejo vir resnice. |
| SleekDB | Primerno zaDokumentna zbirka podatkov z navadnimi datotekami JSON v PHP, brez odvisnosti drugih ponudnikov, ki shranjuje podatke brez sheme. Njen jezik poizvedb API vključuje združevanje, iskanje po besedilu, group by in having ter filtre za gnezdene lastnosti. | Razlika v primerjavi z Storhstorh združuje svojo dokumentno shrambo s segmentiranim dnevnikom, ki dovoljuje samo dodajanje, in čakalno vrsto na osnovi dnevnika pod enim korenom ter vsak zapis sinhronizira z diskom, preden potrdi shranjevanje. Združevanje ni del storh; zbirke za ta namen potisne v SQLite ali MySQL. |
Vprašanja in odgovori
Kratki odgovori iz dokumentacije za Storh.
Da. DocStore serializira spremembe z zaklepanjem zapisovanja na ravni zbirke, pri sočasnih zapisih istega ID-ja pa zmaga zadnje preimenovanje. Prevzemi opravil v čakalni vrsti zadržijo zaklep čakalne vrste, zato dva delavca ne moreta prevzeti istega čakajočega opravila.
Da. Branje sprejme komentarje in zaključne vejice, toda naslednje put() za ta ID prepiše datoteko v kompaktni obliki JSON in jih odstrani. V načinu predpomnilnika TRUST spremembe datotek zunaj storh niso zaznane.
Točkovno branje po ID-ju ostane hitro, dokler datotečni sistem zmore število datotek. Nepoindeksirani pregledi polj v DocStore se upočasnijo pri približno 10k zapisih, zato indeksirajte polja, po katerih filtrirate. Pregledi segmentiranih dnevnikov in branje obsegov dobro delujejo do približno 1M zapisov.
Zapisi se sinhronizirajo z diskom in objavijo z atomskim preimenovanjem; ob ponovnem odprtju dnevnika ali čakalne vrste se nepopolni zaključki skrajšajo do zadnjega potrjenega dogodka. Trajnost ob izpadu elektrike je še vedno odvisna od tega, ali datotečni sistem in možnosti priklopa upoštevajo te sinhronizacije.
Ne. Zbirke lahko z SqlMirror potisnete v SQLite ali MySQL za združevanje, iskanje in poročanje. Atomsko zapisovanje več zapisov naj ostane naloga prave zbirke podatkov, ki je glavni vir podatkov.
Ne. Queue ni splošna shramba zapisov, vsebina opravila pa se po dokončanju zavrže.
Začnite s hitrim začetkom, nato v razdelku Choosing an engine izberite DocStore, SegmentedLog ali Queue glede na svojo obremenitev.