跳转到正文

UUIDv7

每个 storh 记录 id 都是一个 UUIDv7:48 位毫秒时间戳后接随机熵,并格式化为标准的 36 字符 UUID。由于时间戳位于开头,id 会按创建时间排序;这一特性支撑了 storh 的大部分功能:游标分页(after($id))、时间范围读取、跳过日志中的分段,以及在各处保持稳定排序。

PHP
$id = Storh\UuidV7::generate();

Storh\UuidV7::is_valid($id);          // bool, accepts upper and lower case
Storh\UuidV7::assert_valid($id);      // throws StorageException instead
$timestampMs = Storh\UuidV7::timestamp_ms($id);

在同一进程内,生成过程具有单调性:同一毫秒内创建的 id 会递增前一个 id 的随机熵,而不是重新随机生成,因此快速连续写入时仍会按创建顺序排序。

按时间定位

对于时间窗口,storh 会根据毫秒时间戳计算可能的最小和最大 UUIDv7,并将 id 与这些边界进行比较:

PHP
$query = Storh\RecordQuery::all()->time_range_ms(
    1_700_000_000_000,
    1_700_000_060_000,
);

$lower = Storh\UuidV7::min_for_timestamp_ms(1_700_000_000_000);
$upper = Storh\UuidV7::max_for_timestamp_ms(1_700_000_060_000);

因此,按时间范围读取时无需在记录数据中设置时间戳字段:id 本身就包含创建时间。

提供自定义 id

所有引擎都支持为每次写入指定显式 id($docs->put($data, $id)),也支持在构造函数中传入 id_generator 可调用对象。无论通过哪种方式提供的 id 都会验证是否为 UUIDv7,因此自定义生成器必须生成此类 id;测试套件通过确定性生成器创建可复现的测试数据。UuidV7::reset_for_tests() 会在测试用例之间清除进程级单调状态。