Storh
Fillagring i första hand för PHP: JSONC-dokument, segmenterade loggar med endast tillägg och loggbaserade köer med UUIDv7-id:n.
composer require storh/storhSenaste versionen v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();I praktiken
Snabbstarten i två delar: ett dokument i en lagringsrot, sedan en loggpost och ett köjobb bredvid.
En rot, tre motorer
StorageRoot::resolve() normaliserar en baskatalog och ett namnrymd till en rot, och varje motor skapar sin egen katalog där vid första användningen.
Varje motor returnerar StorageRecord-objekt med id() och data(). Kön lägger till varje anspråk och slutförande i sin händelselogg.
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());
}JSONC-dokumentlager
En fil i JSONC per post, UUIDv7-id:n, sharding med två tecken från UUIDs sista grupp, atomärt utbyte och strömmande fältfilter.
Segmenterad logg
Endast tillägg i segment med rader prefixade med längd och kontrollsumma JSON, glesa index, läsning med markör och tidsintervall, kraschåterställning och komprimering.
Loggkö
Jobb går genom väntande, bearbetas och klara tillstånd med kompakta, endast tilläggsbaserade köhändelser.
UUIDv7-poster
Sorterbara, tidsadresserbara id:n för stabila markörer, begränsade genomsökningar och lagringssökvägar som passar för shardning.
Atomiska skrivningar
Skrivningar till temporära filer och atomiska namnbyten håller posterna intakta. Efter en skrivarkrasch rensar nästa öppning bort dess föräldralösa temporärfiler.
Återställning efter ofullständig skrivning
Segmentläsningar validerar längd- och kontrollsummefält; återställning kapar ofullständiga avslutande rader.
Filer i första hand
Ingen databasserver, ingen ramverksadapter, inga Composer-körningspaket; anroparen skickar in en katalog.
Läser JSONC
Postfiler kan innehålla kommentarer och avslutande kommatecken. storh skriver kompakt JSON på en enda rad, så kommentarerna finns kvar fram till nästa skrivning.
Frågebyggare
Flytande frågor som where('status')->in([...]) på DocStore och SegmentedLog; DocStore använder sekundära index där sådana finns.
Sekundära index
Likhets-, unikhets- och intervallindex lagras som filer bredvid samlingen, härleds från posterna och kan byggas om när som helst.
Scheman
Valfria samlingsscheman validerar varje skrivning och anger vilka fält som ska indexeras.
SQL-spegel
Skicka samlingar till SQLite eller MySQL för kopplingar, sökning och rapportering medan filerna förblir kanoniska. Kräver ext-pdo eller ext-mysqli endast vid användning.
Varför Storh
En katalog, inte en server
Du anger en baskatalog och storh skriver där. Det kräver PHP 8.2 och ext-json, utan Composer-körningspaket eller ramverksadapter.
En postform, tre layouter
Dokument, loggar och köer lagrar alla ett UUIDv7-id plus en dataarray. Välj disklayout efter arbetsbelastning och håll alla tre under en rot.
Kontroller du kan köra
verify() kontrollerar index och loggtillstånd mot en fullständig genomsökning av filerna. repair() sätter skadade poster i karantän och kapar ofullständiga loggavslut, och CLI skriver ut JSON för cron-jobb och hälsokontroller.
Riktmärken med tillhörande konfiguration
README publicerar medianvärden för 50,000 poster per motor på en Apple M1 Pro med PHP 8.5, till exempel 5.6 µs per punktläsning. Varje skrivning i dessa körningar synkroniseras med fsync, så skrivhastigheten beror på filsystemet.
Jämfört med
storh är fillagring i första hand snarare än en relationsbaserad frågemotor, så dessa verktyg utför vissa uppgifter som den utelämnar.
| Verktyg | Bra på | Skillnaden jämfört med Storh |
|---|---|---|
| SQLite | Bra påEn fristående SQL-motor i en enda fil, med serialiserbara ACID-transaktioner som består vid programkrasch eller strömavbrott. Dokumentationen beskriver den som en ersättning för ad hoc-datafiler. | Skillnaden jämfört med Storhstorh har en JSON-fil per post och kärnan kräver ingen PDO-drivrutin. Den saknar transaktioner över flera poster, och dokumentationen hänvisar sådant arbete till en riktig databas. Samlingar kan skickas till SQLite för kopplingar och rapportering medan filerna förblir kanoniska. |
| MySQL | Bra påEn relationsdatabas som körs av en flertrådad SQL-server, med klientprogram och bibliotek, administrationsverktyg och ett brett utbud av API:er. | Skillnaden jämfört med Storhstorh körs inuti processen PHP mot en katalog, så det finns ingen server att driva. För kopplingar, sökning och rapportering speglar den samlingar till MySQL, även via ett befintligt mysqli-handtag, och filerna förblir den enda sanningskällan. |
| SleekDB | Bra påEn dokumentdatabas med platta filer i PHP utan tredjepartsberoenden, som lagrar schemalösa data som vanliga JSON-filer. Frågespråket API omfattar kopplingar, textsökning, group by och having samt filter på kapslade egenskaper. | Skillnaden jämfört med Storhstorh kombinerar sitt dokumentlager med en segmenterad logg med endast tillägg och en loggbaserad kö under en rot och synkroniserar varje skrivning med fsync innan den rapporterar att den har lagrats. Kopplingar ingår inte i storh; samlingar skickas till SQLite eller MySQL för detta. |
Frågor och svar
Korta svar från dokumentationen för Storh.
Ja. DocStore serialiserar ändringar med ett skrivlås på samlingsnivå, och samtidiga skrivningar till samma id avgörs av det senaste namnbytet. Köanspråk håller kön låst, så två arbetare kan inte göra anspråk på samma väntande jobb.
Ja. Läsningar godtar kommentarer och avslutande kommatecken, men nästa put() till det id:t skriver om filen som kompakt JSON och tar bort dem. Med cacheläget TRUST upptäcks inte filer som ändrats utanför storh.
Punktläsningar via id förblir snabba så länge filsystemet klarar filantalet. Oindexerade fältsökningar i DocStore blir långsammare efter ungefär 10k poster, så ange index för de fält du filtrerar på. Genomsökningar och intervalläsningar i segmenterade loggar fungerar bra upp till ungefär 1M poster.
Skrivningar synkroniseras med fsync och publiceras genom atomiskt namnbyte, och när en logg eller kö öppnas igen kapas ofullständiga avslut till den senaste bekräftade händelsen. Hållbarhet vid strömavbrott beror fortfarande på att filsystemet och monteringsalternativen respekterar dessa synkroniseringar.
Nej. Skicka samlingar till SQLite eller MySQL med SqlMirror för kopplingar, sökning och rapportering. Atomiska skrivningar över flera poster hör fortfarande hemma i en riktig databas som system of record.
Nej. Queue är inget allmänt postlager, och jobbets nyttolast tas bort när jobbet slutförs.
Börja med snabbstarten och använd sedan Välja motor för att anpassa DocStore, SegmentedLog eller Queue till din arbetsbelastning.