Перейти до вмісту

Storh

Записи на основі файлів для PHP: документи JSONC, сегментовані журнали лише для дописування та черги на основі журналів з ідентифікаторами UUIDv7.

Термінал
composer require storh/storh

Останній випуск v0.5.2 MIT PHP 8.2+

На практиці

Короткий посібник із двох частин: документ у кореневому каталозі сховища, а поруч із ним — запис журналу та завдання черги.

Один кореневий каталог, три рушії

StorageRoot::resolve() нормалізує базовий каталог і простір імен у кореневий каталог, а під час першого використання кожен рушій створює в ньому власний каталог.

Кожен рушій повертає об’єкти StorageRecord з id() і data(). Черга додає кожне отримання завдання та його завершення до журналу подій.

Документи
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());

Сховище документів JSONC

Один файл JSONC на запис, ідентифікатори UUIDv7, шардування за двома символами з останньої групи UUID, атомарна заміна та потокові фільтри полів.

Сегментований журнал

Сегменти лише для дописування з рядками JSON, що мають префікси довжини й контрольної суми, розріджені індекси, читання за курсором і часовим діапазоном, відновлення після збою та ущільнення.

Черга журналу

Завдання переходять між станами очікування, обробки та завершення за допомогою компактних подій черги, що додаються до журналу.

Записи UUIDv7

Сортовані ідентифікатори з часовою адресацією для стабільних курсорів, обмеженого сканування та шляхів зберігання, зручних для шардування.

Атомарний запис

Запис у тимчасовий файл і атомарне перейменування забезпечують цілісність записів. Після аварійного завершення роботи записувача наступне відкриття видаляє його осиротілі тимчасові файли.

Відновлення після часткового запису

Під час читання сегментів перевіряються поля довжини й контрольної суми; відновлення обрізає неповні кінцеві рядки.

Спершу файли

Без сервера бази даних, адаптера фреймворку та пакетів середовища виконання Composer; викликач передає каталог.

Читання JSONC

Файли записів можуть містити коментарі й кінцеві коми. Під час запису storh створює компактний однорядковий JSON, тому коментарі зберігаються до наступного запису.

Конструктор запитів

Ланцюжки запитів на кшталт where('status')->in([...]) у DocStore та SegmentedLog; DocStore використовує вторинні індекси, якщо вони є.

Вторинні індекси

Індекси рівності, унікальності й діапазонів зберігаються у файлах поруч із колекцією, формуються на основі записів і можуть бути перебудовані будь-коли.

Схеми

Необов’язкові схеми колекцій перевіряють кожен запис і визначають, для яких полів створювати індекси.

Дзеркало SQL

Передавайте колекції в SQLite або MySQL для об’єднань, пошуку й звітності, залишаючи файли канонічним джерелом даних. Потрібен ext-pdo або ext-mysqli, лише якщо цю функцію використовують.

Чому Storh

Каталог замість сервера

Ви передаєте базовий каталог, і storh записує дані в нього. Потрібні PHP 8.2 та ext-json, без пакетів середовища виконання Composer і адаптера фреймворку.

Одна форма запису, три способи зберігання

Документи, журнали й черги зберігають ідентифікатор UUIDv7 і масив даних. Виберіть спосіб зберігання на диску для свого завдання та розмістіть усі три рушії в одному кореневому каталозі.

Перевірки, які можна виконати

verify() перевіряє індекси й стан журналу, скануючи всі файли. repair() поміщає пошкоджені записи в карантин і обрізає неповні кінцеві фрагменти журналу, а CLI виводить JSON для завдань cron та перевірок стану.

Бенчмарки з описом умов

README публікує медіанні показники для 50,000 записів на рушій на комп’ютері Apple M1 Pro з PHP 8.5, наприклад 5.6 µs для читання одного запису. Усі записи в цих запусках синхронізуються через fsync, тому швидкість запису залежить від файлової системи.

Порівняно з

storh — це файлове сховище, а не рушій реляційних запитів, тому ці інструменти виконують деякі завдання, які воно не охоплює.

Storh у порівнянні з іншими інструментами
SQLite ПеревагиАвтономний рушій SQL в одному файлі із серіалізованими транзакціями ACID, що зберігають цілісність після аварійного завершення програми чи збою живлення. У документації його описано як заміну спеціально створеним файлам даних. Відмінність від Storhstorh зберігає кожен запис в окремому файлі JSON, а для його ядра не потрібен драйвер PDO. Транзакцій між кількома записами немає; документація радить використовувати для цього повноцінну базу даних. Колекції можна передавати в SQLite для об’єднань і звітності, залишаючи файли канонічним джерелом даних.
MySQL ПеревагиРеляційна база даних, яку обслуговує багатопотоковий сервер SQL, із клієнтськими програмами й бібліотеками, адміністративними інструментами та широким набором API. Відмінність від Storhstorh працює в процесі PHP із каталогом, тому керувати сервером не потрібно. Для об’єднань, пошуку й звітності він копіює колекції в MySQL, зокрема через наявний дескриптор mysqli, а файли залишаються джерелом істини.
SleekDB ПеревагиДокументна база даних на основі файлів у PHP без сторонніх залежностей, що зберігає дані без схеми у звичайних файлах JSON. Її мова запитів API підтримує об’єднання, текстовий пошук, group by і having, а також фільтри для вкладених властивостей. Відмінність від Storhstorh поєднує сховище документів із сегментованим журналом лише для дописування та чергою на його основі в одному кореневому каталозі й виконує fsync для кожного запису перед підтвердженням його збереження. Об’єднання не входять до storh; для них колекції можна передати в SQLite або MySQL.

Запитання та відповіді

Короткі відповіді з документації Storh.

Почніть із короткого посібника, а потім перегляньте розділ «Вибір рушія», щоб підібрати DocStore, SegmentedLog або Queue для свого завдання.