Storh
سجلات تعتمد على الملفات أولًا لـ PHP: مستندات JSONC، وسجلات مجزأة للإضافة فقط، وطوابير مدعومة بالسجلات بمعرّفات UUIDv7.
composer require storh/storhأحدث إصدار v0.5.2 MIT PHP 8.2+
$pages = $docs
->query()
->where('kind')->eq('page')
->orderBy('title')
->limit(20)
->get();في التطبيق العملي
دليل البدء السريع في جزأين: مستند في جذر التخزين، ثم إدخال سجل ومهمة في طابور بجواره.
جذر واحد وثلاثة محركات
يهيئ 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());$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
ملف 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 لكل قراءة مباشرة. تُزامَن كل كتابة على القرص في تلك التشغيلات، لذا تعتمد معدلات الكتابة على نظام الملفات.
مقارنة مع
يعتمد storh على الملفات بدلًا من كونه محرك استعلامات علائقيًا، لذا تنفذ هذه الأدوات بعض المهام التي لا يوفرها.
| الأداة | مناسب لـ | الاختلاف عن Storh |
|---|---|---|
| SQLite | مناسب لـمحرك SQL مستقل في ملف واحد، مع معاملات ACID قابلة للتسلسل وتصمد أمام تعطل البرنامج أو انقطاع الطاقة. وتعرض وثائقه إياه بديلًا لملفات البيانات المرتجلة. | الاختلاف عن Storhيحتفظ storh بملف JSON واحد لكل سجل، ولا يحتاج في أساسه إلى برنامج تشغيل PDO. لا يدعم معاملات متعددة السجلات، وتحيل وثائقه هذه المهمة إلى قاعدة بيانات فعلية. ويمكنه دفع المجموعات إلى SQLite لإجراء عمليات الربط وإعداد التقارير مع بقاء الملفات هي المصدر المعتمد. |
| MySQL | مناسب لـقاعدة بيانات علائقية يقدمها خادم SQL متعدد الخيوط، مع برامج ومكتبات للعميل وأدوات إدارية ومجموعة واسعة من واجهات API. | الاختلاف عن Storhيعمل storh داخل عملية PHP على مجلد، لذا لا يوجد خادم لإدارته. ولإجراء عمليات الربط والبحث وإعداد التقارير، ينسخ المجموعات إلى MySQL، أيضًا عبر مقبض mysqli موجود، وتظل الملفات مصدر الحقيقة. |
| SleekDB | مناسب لـقاعدة بيانات مستندات مسطحة الملفات في PHP بلا اعتماديات خارجية، تخزن بيانات بلا مخطط كملفات JSON عادية. تتضمن لغة الاستعلام API عمليات الربط والبحث النصي والتجميع والتصفية على الخصائص المتداخلة. | الاختلاف عن Storhيجمع storh بين مخزن المستندات وسجل مجزأ لا يقبل إلا الإضافة وطابور مدعوم بالسجلات تحت جذر واحد، ويزامن كل كتابة على القرص قبل الإبلاغ عن حفظها. لا يدعم storh عمليات الربط؛ بل يدفع المجموعات إلى SQLite أو MySQL لإجرائها. |
الأسئلة والأجوبة
إجابات موجزة من توثيق Storh.
نعم. يرتب DocStore عمليات التعديل باستخدام قفل كتابة على مستوى المجموعة، وعند الكتابة المتزامنة للمعرّف نفسه تفوز آخر عملية إعادة تسمية. وتحتفظ مطالبات الطابور بقفله، لذا لا يطالب عاملان بالمهمة نفسها المعلقة.
نعم. تقبل القراءات التعليقات والفواصل الزائدة، لكن الكتابة التالية إلى ذلك المعرّف put() تعيد كتابة الملف بصيغة JSON موجزة وتحذفها. في وضع التخزين المؤقت TRUST، لا تُكتشف التغييرات التي تُجرى على الملفات خارج storh.
تظل القراءات المباشرة بالمعرّف سريعة ما دام نظام الملفات قادرًا على التعامل مع عدد الملفات. تتباطأ عمليات مسح حقول DocStore غير المفهرسة بعد نحو 10k سجل، لذا عرّف فهارس للحقول التي تصفيها. وتظل عمليات المسح وقراءات النطاق في السجل المجزأ مريحة حتى نحو مليون سجل.
تُزامَن الكتابات على القرص وتُنشر بإعادة تسمية ذرية، وعند إعادة فتح سجل أو طابور تُقتطع النهايات المبتورة حتى آخر حدث معتمد. وتعتمد متانة البيانات عند انقطاع الطاقة على التزام نظام الملفات وخيارات التركيب بعمليات المزامنة هذه.
لا. ادفع المجموعات إلى SQLite أو MySQL باستخدام SqlMirror لإجراء عمليات الربط والبحث وإعداد التقارير. وتظل الكتابات الذرية متعددة السجلات من مهام قاعدة بيانات فعلية تكون مصدر السجلات المعتمد.
لا. الطابور ليس مخزنًا عامًا للسجلات، وتُحذف حمولة المهمة عند اكتمالها.
ابدأ بدليل البدء السريع، ثم استخدم قسم اختيار المحرك لمواءمة DocStore أو SegmentedLog أو Queue مع عبء العمل.