Storh
PHP için dosya öncelikli kayıtlar: JSONC belgeleri, yalnızca eklemeli segmentli günlükler ve günlük destekli kuyruklar; UUIDv7 kimlikleriyle.
composer require storh/storhEn son sürüm v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();Uygulamada
İki parçalı hızlı başlangıç: depolama kökünde bir belge, ardından yanında bir günlük girdisi ve kuyruk işi.
Tek kök, üç motor
StorageRoot::resolve() bir temel dizinle ad alanını tek bir kökte birleştirir ve her motor ilk kullanımda kendi dizinini bu kökün altında oluşturur.
Her motor, id() ve data() içeren StorageRecord nesneleri döndürür. Kuyruk, her alındı ve tamamlandı olayını kendi olay günlüğüne ekler.
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 Belge Deposu
Kayıt başına bir JSONC dosyası, UUIDv7 kimlikleri, UUID'nin son grubundan iki karaktere göre parçalama, atomik değiştirme ve akış halinde alan filtreleri.
Segmentli Günlük
Uzunluk ve sağlama toplamı önekleri içeren JSON satırlarından oluşan, yalnızca eklemeli segmentler; seyrek indeksler, imleç ve zaman aralıklı okumalar, çökme kurtarma ve sıkıştırma.
Günlük Kuyruğu
İşler, yalnızca eklemeli ve kompakt kuyruk olayları kullanılarak bekliyor, işleniyor ve tamamlandı durumları arasında ilerler.
UUIDv7 Kayıtları
Tutarlı imleçler, sınırlandırılmış taramalar ve parçalamaya uygun depolama yolları için sıralanabilir, zaman üzerinden adreslenebilir kimlikler.
Atomik Yazmalar
Geçici dosyaya yazma ve atomik yeniden adlandırma, kayıtları bütün halde tutar. Yazıcı çöktükten sonra depo bir sonraki açıldığında sahipsiz geçici dosyaları temizler.
Yarım Yazma Kurtarma
Segment okumaları uzunluk ve sağlama toplamı alanlarını doğrular; kurtarma, sondaki kısmi satırları kısaltır.
Dosya Öncelikli
Veritabanı sunucusu, çatı adaptörü veya Composer çalışma zamanı paketi gerekmez; çağıranlar bir dizin iletir.
Okumalar JSONC
Kayıt dosyalarında yorumlar ve sondaki virgüller bulunabilir. storh, tek satırlık kompakt JSON yazar; dolayısıyla yorumlar bir sonraki yazmaya kadar kalır.
Sorgu Oluşturucu
DocStore ve SegmentedLog'da where('status')->in([...]) gibi akıcı sorgular; DocStore, varsa ikincil indeksleri kullanır.
İkincil İndeksler
Koleksiyonun yanında dosya olarak saklanan eşitlik, benzersizlik ve aralık indeksleri kayıtlardan türetilir ve istenen zamanda yeniden oluşturulabilir.
Şemalar
İsteğe bağlı koleksiyon şemaları her yazmayı doğrular ve hangi alanların indeks alacağını belirtir.
SQL Yansıması
Dosyalar asıl kaynak olarak kalırken birleştirme, arama ve raporlama için koleksiyonları SQLite veya MySQL içine aktarın. Yalnızca kullanıldığında ext-pdo veya ext-mysqli gerekir.
Storh neden tercih edilmeli
Sunucu değil, bir dizin
Bir temel dizin sağlarsınız; storh oraya yazar. PHP 8.2 ve ext-json gerekir; Composer çalışma zamanı paketleri veya çatı adaptörü gerekmez.
Tek kayıt biçimi, üç düzen
Belgeler, günlükler ve kuyrukların tümü bir UUIDv7 kimliğiyle birlikte bir veri dizisi saklar. İş yükünüze göre disk düzenini seçin ve üçünü de tek bir kök altında tutun.
Çalıştırabileceğiniz denetimler
verify(), indeksleri ve günlük durumunu dosyaların tam taramasıyla karşılaştırır. repair() bozuk kayıtları karantinaya alıp yarım kalmış günlüklerin sonunu kısaltır; CLI ise cron işleri ve sağlık denetimleri için JSON çıktısı verir.
Kurulumu belirtilen performans ölçümleri
README, motor başına 50,000 kayıt için ortanca değerleri PHP 8.5 yüklü bir Apple M1 Pro üzerinde yayımlar; örneğin tekil okuma başına 5.6 µs. Bu çalıştırmalardaki her yazma fsync ile diske aktarılır, bu nedenle yazma hızları dosya sistemine bağlıdır.
Karşılaştırma
storh ilişkisel bir sorgu motoru değil, dosya öncelikli bir depolama çözümüdür; bu nedenle bu araçlar onun sunmadığı bazı işleri yapar.
| Araç | Şu konularda başarılı | Storh ile farkı |
|---|---|---|
| SQLite | Şu konularda başarılıTek bir dosyada sunulan, kendi kendine yeterli bir SQL motoru. Program çökmesine veya elektrik kesintisine rağmen geçerliliğini koruyan, seri hâle getirilebilir ACID işlemlerini destekler. Belgeleri, gelişigüzel veri dosyalarının yerine kullanılabileceğini belirtir. | Storh ile farkıstorh, kayıt başına bir JSON dosyası tutar ve çekirdeği hiçbir PDO sürücüsü gerektirmez. Birden çok kayıt üzerinde işlem desteği yoktur; belgeler bu iş için gerçek bir veritabanı kullanılmasını önerir. Dosyalar asıl kaynak olarak kalırken birleştirme ve raporlama için koleksiyonları SQLite içine aktarabilir. |
| MySQL | Şu konularda başarılıÇok iş parçacıklı bir SQL sunucusu tarafından sunulan ilişkisel veritabanı; istemci programları ve kitaplıkları, yönetim araçları ve geniş bir API yelpazesi sunar. | Storh ile farkıstorh, PHP süreci içinde bir dizine karşı çalışır; dolayısıyla yönetilecek bir sunucu yoktur. Birleştirme, arama ve raporlama için koleksiyonları MySQL içine yansıtır; bunu mevcut bir mysqli tanıtıcısı üzerinden de yapabilir ve dosyaları doğruluk kaynağı olarak tutar. |
| SleekDB | Şu konularda başarılıPHP ile yazılmış, üçüncü taraf bağımlılığı olmayan düz dosyalı bir belge veritabanı; şemasız verileri yalın JSON dosyalarında saklar. Sorgu API; birleştirme, metin arama, GROUP BY ve HAVING ile iç içe özelliklere yönelik filtreleri kapsar. | Storh ile farkıstorh, belge deposunu yalnızca eklemeli segmentli bir günlük ve günlük destekli bir kuyrukla tek bir kök altında birleştirir; her yazmanın kaydedildiğini bildirmeden önce fsync işlemi uygular. Birleştirmeler storh kapsamında değildir; bunun için koleksiyonları SQLite veya MySQL içine aktarır. |
Sorular ve yanıtlar
Storh dokümantasyonundan kısa yanıtlar.
Evet. DocStore, değişiklikleri koleksiyon düzeyinde bir yazma kilidiyle sıralar; aynı kimliğe yapılan eşzamanlı yazmalarda son yeniden adlandırma kazanır. Kuyruk işlerinin alınması sırasında kuyruk kilitlenir; böylece iki çalışan aynı bekleyen işi alamaz.
Evet. Okumalar yorumları ve sondaki virgülleri kabul eder, ancak o kimliğe yapılan bir sonraki put(), dosyayı kompakt JSON biçiminde yeniden yazar ve bunları kaldırır. TRUST önbellek modunda, storh dışından değiştirilen dosyalar algılanmaz.
Dosya sistemi dosya sayısını kaldırabildiği sürece kimliğe göre tekil okumalar hızlı kalır. DocStore'da indekssiz alan taramaları yaklaşık 10 bin kayıttan sonra yavaşlar; bu nedenle filtrelediğiniz alanlar için indeks tanımlayın. Segmentli günlük taramaları ve aralık okumaları yaklaşık 1 milyon kayda kadar rahatça çalışır.
Yazmalar fsync ile diske aktarılır ve atomik yeniden adlandırmayla yayımlanır. Bir günlük veya kuyruk yeniden açıldığında yarım kalan son bölüm, en son işlenen olaya kadar kısaltılır. Elektrik kesintisine karşı veri kalıcılığı yine de dosya sisteminin ve bağlama seçeneklerinin bu eşitleme işlemlerine uyup uymamasına bağlıdır.
Hayır. Birleştirme, arama ve raporlama için koleksiyonları SqlMirror ile SQLite veya MySQL içine aktarın. Birden çok kaydı atomik olarak yazma işi, kayıt sistemi olarak kullanılan gerçek bir veritabanına aittir.
Hayır. Kuyruk, genel amaçlı bir kayıt deposu değildir; iş tamamlandığında yükü silinir.
Hızlı başlangıç kılavuzuyla başlayın; ardından iş yükünüze uygun DocStore, SegmentedLog veya Queue motorunu seçmek için Motor seçimi bölümüne bakın.