Treci la conținut

Storh

Înregistrări bazate pe fișiere pentru PHP: documente JSONC, jurnale segmentate doar pentru adăugare și cozi susținute de jurnale, cu id-uri UUIDv7.

Terminal
composer require storh/storh

Cea mai recentă versiune v0.5.2 MIT PHP 8.2+

În practică

Ghidul de pornire rapidă în două părți: un document într-un director rădăcină de stocare, apoi o intrare în jurnal și o sarcină în coadă alături.

O rădăcină, trei motoare

StorageRoot::resolve() normalizează un director de bază și un spațiu de nume într-o rădăcină, iar fiecare motor își creează propriul director în interiorul acesteia la prima utilizare.

Fiecare motor returnează obiecte StorageRecord cu id() și data(). Coada adaugă fiecare revendicare și finalizare în jurnalul său de evenimente.

Documente
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());

Stocare de documente JSONC

Un fișier JSONC pentru fiecare înregistrare, id-uri UUIDv7, partiționare după două caractere din grupul final al UUID, înlocuire atomică și filtre de câmpuri transmise în flux.

Jurnal segmentat

Segmente doar cu adăugare, alcătuite din linii JSON prefixate cu lungimea și suma de control, indexuri rarefiate, citiri cu cursor și pe interval de timp, recuperare după căderi și compactare.

Coadă de jurnale

Sarcinile trec prin stările în așteptare, în procesare și finalizate, folosind evenimente compacte de coadă, doar cu adăugare.

Înregistrări UUIDv7

ID-uri sortabile, adresabile în timp, pentru cursoare stabile, scanări limitate și căi de stocare potrivite pentru shard-uri.

Scrieri atomice

Scrierile într-un fișier temporar și redenumirile atomice păstrează integritatea înregistrărilor. După blocarea unui proces de scriere, următoarea deschidere elimină fișierele temporare orfane.

Recuperare după scrieri incomplete

Citirile segmentelor validează câmpurile de lungime și checksum; recuperarea trunchiază liniile incomplete de la final.

Fișiere înainte de toate

Fără server de baze de date, fără adaptor pentru framework, fără pachete runtime Composer; apelanții transmit un director.

Citește JSONC

Fișierele înregistrărilor pot conține comentarii și virgule finale. Scrierile storh folosesc JSON compacte, pe o singură linie, așa că comentariile rămân până la următoarea scriere.

Generator de interogări

Interogări fluente precum where('status')->in([...]) în DocStore și SegmentedLog; DocStore folosește indexuri secundare acolo unde există.

Indexuri secundare

Indexuri de egalitate, unice și de interval, stocate ca fișiere lângă colecție, derivate din înregistrări și reconstruibile oricând.

Scheme

Schemele opționale ale colecțiilor validează fiecare scriere și declară câmpurile indexate.

SQL Mirror

Împingeți colecțiile în SQLite sau MySQL pentru îmbinări, căutare și raportare, păstrând fișierele drept sursă canonică. Necesită ext-pdo sau ext-mysqli doar când sunt folosite.

De ce Storh

Un director, nu un server

Transmiteți un director de bază, iar storh scrie acolo. Necesită PHP 8.2 și ext-json, fără pachete runtime Composer și fără adaptor pentru framework.

O formă de înregistrare, trei structuri

Documentele, jurnalele și cozile stochează toate un ID UUIDv7 și un tablou de date. Alegeți structura pe disc în funcție de sarcină și păstrați-le pe toate trei sub aceeași rădăcină.

Verificări pe care le puteți rula

verify() verifică indexurile și starea jurnalelor printr-o scanare completă a fișierelor. repair() pune în carantină înregistrările corupte și trunchiază finalurile incomplete ale jurnalelor, iar CLI afișează JSON pentru sarcinile cron și verificările de stare.

Benchmark-uri cu configurația aferentă

README publică medianele pentru 50,000 de înregistrări per motor, pe un Apple M1 Pro cu PHP 8.5, de exemplu 5.6 µs pentru o citire punctuală. Fiecare scriere din aceste rulări este sincronizată cu fsync, așa că ratele de scriere depind de sistemul de fișiere.

Comparativ cu

storh este o stocare bazată pe fișiere, nu un motor de interogare relațional, așa că aceste instrumente îndeplinesc unele sarcini pe care acesta nu le acoperă.

Storh în comparație cu alte instrumente
SQLite Potrivit pentruUn motor SQL autonom, într-un singur fișier, cu tranzacții ACID serializabile care rezistă la blocarea programului sau la o pană de curent. Documentația îl prezintă ca înlocuitor pentru fișierele de date ad-hoc. Diferența față de Storhstorh păstrează un fișier JSON per înregistrare, iar nucleul său nu necesită driver PDO. Nu oferă tranzacții pentru mai multe înregistrări, iar documentația recomandă o bază de date adevărată pentru acest tip de operațiuni. Poate împinge colecțiile în SQLite pentru îmbinări și raportare, păstrând fișierele drept sursă canonică.
MySQL Potrivit pentruO bază de date relațională deservită de un server SQL multithread, cu programe și biblioteci client, instrumente administrative și o gamă largă de API-uri. Diferența față de Storhstorh rulează în procesul PHP, lucrând cu un director, așa că nu există un server de administrat. Pentru îmbinări, căutare și raportare, reflectă colecțiile în MySQL, inclusiv printr-un handle mysqli existent, iar fișierele rămân sursa adevărului.
SleekDB Potrivit pentruO bază de date documentară cu fișiere plate în PHP, fără dependențe de la terți, care stochează date fără schemă în fișiere JSON simple. API pentru interogări include îmbinări, căutare text, group by și having, precum și filtre pentru proprietăți imbricate. Diferența față de Storhstorh asociază depozitului de documente un jurnal segmentat, doar cu adăugare, și o coadă bazată pe jurnal, toate sub aceeași rădăcină, și folosește fsync pentru fiecare scriere înainte de a confirma stocarea. Îmbinările nu fac parte din storh; pentru acestea, împinge colecțiile în SQLite sau MySQL.

Întrebări și răspunsuri

Răspunsuri scurte din documentația Storh.

Începeți cu ghidul de pornire rapidă, apoi folosiți Alegerea unui motor pentru a potrivi DocStore, SegmentedLog sau Queue cu sarcina dumneavoastră.