본문으로 건너뛰기

Storh

PHP용 파일 우선 레코드: JSONC 문서, 추가 전용 분할 로그, UUIDv7 ID 기반 로그 큐.

터미널
composer require storh/storh

최신 릴리스 v0.5.2 MIT PHP 8.2+

실제 사용

두 부분으로 구성된 빠른 시작입니다. 저장소 루트의 문서부터 시작해 그 옆에 로그 항목과 큐 작업을 추가합니다.

루트 하나, 엔진 세 개

StorageRoot::resolve()는 기본 디렉터리와 네임스페이스를 루트로 정규화하며, 각 엔진은 처음 사용할 때 자체 디렉터리를 그 아래에 만듭니다.

각 엔진은 id() 및 data()가 있는 StorageRecord 객체를 반환합니다. 큐는 작업을 가져오고 완료할 때마다 이벤트 로그에 추가합니다.

문서
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 ID, UUID의 마지막 그룹에서 가져온 두 문자로 샤딩, 원자적 교체 및 스트리밍 필드 필터.

분할 로그

길이와 체크섬이 앞에 붙은 JSON 줄로 구성된 추가 전용 세그먼트, 희소 인덱스, 커서 및 시간 범위 읽기, 충돌 복구, 압축을 제공합니다.

로그 큐

작업은 간결한 추가 전용 큐 이벤트를 통해 대기, 처리 중, 완료 상태로 이동합니다.

UUIDv7 레코드

안정적인 커서, 제한된 스캔, 샤드에 적합한 저장 경로를 위한 정렬 가능하고 시간으로 주소 지정 가능한 ID입니다.

원자적 쓰기

임시 파일에 쓴 뒤 원자적으로 이름을 바꿔 레코드가 온전하게 유지됩니다. 작성 중 충돌이 발생한 경우 다음에 열 때 남은 임시 파일을 정리합니다.

부분 쓰기 복구

세그먼트를 읽을 때 길이 및 체크섬 필드를 검증하고, 복구 시 끝부분의 불완전한 줄을 잘라냅니다.

파일 우선

데이터베이스 서버도, 프레임워크 어댑터도, Composer 런타임 패키지도 필요 없습니다. 호출자가 디렉터리를 전달합니다.

JSONC 읽기

레코드 파일에는 주석과 후행 쉼표가 있을 수 있습니다. storh는 간결한 한 줄 JSON를 쓰므로 다음 쓰기 전까지 주석이 유지됩니다.

쿼리 빌더

DocStore와 SegmentedLog에서 where('status')->in([...]) 같은 유연한 쿼리를 사용할 수 있으며, DocStore는 보조 인덱스가 있는 경우 이를 활용합니다.

보조 인덱스

동등성, 고유성 및 범위 인덱스를 컬렉션 옆에 파일로 저장합니다. 레코드에서 생성되며 언제든 다시 만들 수 있습니다.

스키마

선택적 컬렉션 스키마로 모든 쓰기를 검증하고 인덱스를 생성할 필드를 지정할 수 있습니다.

SQL 미러

파일이 기준 데이터로 유지되는 동안 조인, 검색 및 보고를 위해 컬렉션을 SQLite 또는 MySQL에 푸시할 수 있습니다. 사용할 때만 ext-pdo 또는 ext-mysqli가 필요합니다.

Storh를 사용하는 이유

서버 대신 디렉터리

기본 디렉터리를 전달하면 storh가 그곳에 씁니다. PHP 8.2와 ext-json만 필요하며, Composer 런타임 패키지나 프레임워크 어댑터는 필요 없습니다.

레코드 형태 하나, 저장 구조 세 가지

문서, 로그, 큐는 모두 UUIDv7 ID와 데이터 배열을 저장합니다. 작업에 맞게 디스크 저장 구조를 선택하고 세 가지를 모두 하나의 루트 아래에 둘 수 있습니다.

직접 실행할 수 있는 검사

verify()는 전체 파일 스캔 결과와 비교해 인덱스 및 로그 상태를 확인합니다. repair()는 손상된 레코드를 격리하고 잘린 로그 끝부분을 제거하며, CLI는 cron 작업 및 상태 검사에 JSON을 출력합니다.

설정과 함께 제공하는 벤치마크

README는 Apple M1 Pro에서 PHP 8.5를 사용해 엔진별 50,000개 레코드의 중앙값을 공개합니다. 예를 들어 단일 항목 읽기는 5.6 µs입니다. 해당 실행에서 모든 쓰기는 fsync 처리되므로 쓰기 속도는 파일시스템에 따라 달라집니다.

비교 대상

storh는 관계형 쿼리 엔진이 아닌 파일 우선 저장소이므로, 여기서 다루지 않는 작업은 다른 도구로 처리할 수 있습니다.

Storh와 다른 도구 비교
SQLite 잘하는 점자체 완결형 SQL 엔진이 단일 파일에 들어 있으며, 프로그램 충돌이나 정전에도 유지되는 직렬화 가능한 ACID 트랜잭션을 제공합니다. 문서에서는 임시 데이터 파일을 대체하는 용도로 소개합니다. Storh와의 차이점storh는 레코드마다 JSON 파일 하나를 유지하며, 코어에 PDO 드라이버가 필요하지 않습니다. 여러 레코드에 걸친 트랜잭션은 지원하지 않으며, 문서에서는 이 작업에 실제 데이터베이스를 사용하도록 안내합니다. 파일을 기준 데이터로 유지하면서 조인과 보고를 위해 컬렉션을 SQLite에 푸시할 수 있습니다.
MySQL 잘하는 점멀티스레드 SQL 서버가 제공하는 관계형 데이터베이스로, 클라이언트 프로그램과 라이브러리, 관리 도구 및 폭넓은 API를 갖추고 있습니다. Storh와의 차이점storh는 PHP 프로세스 안에서 디렉터리를 대상으로 실행되므로 운영할 서버가 없습니다. 조인, 검색 및 보고를 위해 기존 mysqli 핸들을 사용해 컬렉션을 MySQL에 복제할 수 있으며, 파일은 계속 기준 데이터로 유지됩니다.
SleekDB 잘하는 점PHP의 플랫 파일 문서 데이터베이스로, 서드파티 의존성 없이 스키마 없는 데이터를 일반 JSON 파일로 저장합니다. 쿼리 API에는 조인, 텍스트 검색, group by 및 having, 중첩 속성 필터가 포함됩니다. Storh와의 차이점storh는 문서 저장소에 추가 전용 세그먼트 로그와 로그 기반 큐를 결합해 하나의 루트 아래에 두며, 저장이 완료되었다고 보고하기 전에 모든 쓰기를 fsync 처리합니다. storh에는 조인이 없으며, 이를 위해 컬렉션을 SQLite 또는 MySQL에 푸시합니다.

질문과 답변

Storh 문서의 간단한 답변.

빠른 시작으로 시작한 뒤 엔진 선택 가이드를 참고해 워크로드에 맞는 DocStore, SegmentedLog 또는 Queue를 선택하세요.