Pular para o conteúdo

Storh

Registros com arquivos como base para PHP: documentos JSONC, logs segmentados somente para anexação e filas baseadas em logs com ids UUIDv7.

Terminal
composer require storh/storh

Versão mais recente v0.5.2 MIT PHP 8.2+

Na prática

Início rápido em duas partes: um documento em uma raiz de armazenamento, depois uma entrada de log e uma tarefa na fila ao lado.

Uma raiz, três mecanismos

StorageRoot::resolve() normaliza um diretório-base e um namespace em uma raiz, e cada mecanismo cria seu próprio diretório nela ao ser usado pela primeira vez.

Todos os mecanismos retornam objetos StorageRecord com id() e data(). A fila acrescenta cada solicitação e conclusão ao seu log de eventos.

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

Armazenamento de documentos JSONC

Um arquivo JSONC por registro, ids UUIDv7, fragmentação por dois caracteres do grupo final de UUID, substituição atômica e filtros de campos em fluxo.

Log segmentado

Segmentos somente para anexação com linhas JSON prefixadas pelo comprimento e por checksum, índices esparsos, leituras por cursor e intervalo de tempo, recuperação após falhas e compactação.

Fila de log

As tarefas passam pelos estados pendente, em processamento e concluída usando eventos compactos de fila, somente para anexação.

Registros UUIDv7

Ids ordenáveis e localizáveis por horário para cursores estáveis, varreduras limitadas e caminhos de armazenamento adequados à fragmentação.

Gravações atômicas

Gravações em arquivos temporários e renomeações atômicas mantêm os registros íntegros. Após a falha de um processo de gravação, a próxima abertura remove os arquivos temporários órfãos.

Recuperação de gravações incompletas

As leituras de segmentos validam os campos de comprimento e checksum; a recuperação trunca as linhas finais parciais.

Arquivos como base

Sem servidor de banco de dados, adaptador de framework ou pacotes de runtime de Composer; quem chama informa um diretório.

Leituras JSONC

Os arquivos de registro podem conter comentários e vírgulas finais. storh grava JSON compactos em uma única linha, então os comentários permanecem até a próxima gravação.

Construtor de consultas

Consultas encadeadas como where('status')->in([...]) em DocStore e SegmentedLog; DocStore usa índices secundários quando disponíveis.

Índices secundários

Índices de igualdade, unicidade e intervalo armazenados como arquivos junto à coleção, derivados dos registros e reconstruíveis a qualquer momento.

Esquemas

Esquemas de coleção opcionais validam cada gravação e declaram quais campos recebem índices.

Espelhamento de SQL

Envie coleções para SQLite ou MySQL para junções, pesquisas e relatórios enquanto os arquivos permanecem canônicos. Requer ext-pdo ou ext-mysqli somente quando usado.

Por que Storh

Um diretório, sem servidor

Você informa um diretório-base, e storh grava nele. Requer PHP 8.2 e ext-json, sem pacotes de runtime de Composer nem adaptador de framework.

Um formato de registro, três layouts

Documentos, logs e filas armazenam um id UUIDv7 e um array de dados. Escolha o layout em disco para cada carga de trabalho e mantenha os três sob uma única raiz.

Verificações que você pode executar

verify() verifica índices e o estado do log comparando-os com uma varredura completa dos arquivos. repair() coloca registros corrompidos em quarentena e trunca as caudas incompletas do log, e CLI exibe JSON para tarefas cron e verificações de integridade.

Benchmarks com sua configuração

README publica medianas para registros 50,000 por mecanismo em um Apple M1 Pro com PHP 8.5, como 5.6 µs por leitura pontual. Todas as gravações nesses testes são sincronizadas com fsync, então as taxas de gravação dependem do sistema de arquivos.

Comparação com

storh usa arquivos como base de armazenamento, em vez de ser um mecanismo de consultas relacionais; por isso, estas ferramentas executam algumas tarefas que ele não oferece.

Storh em comparação com outras ferramentas
SQLite Ideal paraUm mecanismo SQL independente em um único arquivo, com transações ACID serializáveis que resistem a falhas do programa ou quedas de energia. A documentação o apresenta como substituto para arquivos de dados improvisados. Diferenças em relação a Storhstorh mantém um arquivo JSON por registro e seu núcleo não precisa de um driver PDO. Não oferece transações entre vários registros, e a documentação recomenda usar um banco de dados real para isso. Pode enviar coleções para SQLite para junções e relatórios, mantendo os arquivos canônicos.
MySQL Ideal paraUm banco de dados relacional servido por um servidor SQL multithread, com programas e bibliotecas clientes, ferramentas administrativas e uma ampla variedade de APIs. Diferenças em relação a Storhstorh é executado dentro do processo PHP e opera em um diretório, portanto não há servidor para administrar. Para junções, pesquisas e relatórios, espelha coleções em MySQL, inclusive usando um identificador mysqli existente, e os arquivos continuam sendo a fonte de verdade.
SleekDB Ideal paraUm banco de dados de documentos em arquivos simples, em PHP, sem dependências de terceiros, que armazena dados sem esquema como arquivos JSON simples. Sua API de consultas inclui junções, pesquisa de texto, agrupamento e filtros em propriedades aninhadas. Diferenças em relação a Storhstorh combina seu armazenamento de documentos com um log segmentado somente para anexação e uma fila baseada em log sob uma única raiz, sincronizando cada gravação com fsync antes de informar que foi armazenada. As junções não fazem parte de storh; para isso, ele envia coleções para SQLite ou MySQL.

Perguntas e respostas

Respostas curtas da documentação do Storh.

Comece pelo início rápido e depois use Escolha de um mecanismo para adequar DocStore, SegmentedLog ou Queue à sua carga de trabalho.