
# 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()` 会在测试用例之间清除进程级单调状态。
