
# UUIDv7

Jede storh-Datensatz-ID ist eine UUIDv7: ein Zeitstempel in Millisekunden mit 48 Bit, gefolgt von zufälliger Entropie und formatiert als standardmäßige 36 Zeichen lange UUID. Da der Zeitstempel vorangestellt ist, werden IDs nach Erstellungszeit sortiert. Diese Eigenschaft ermöglicht die meisten Funktionen von storh: Cursor-Paginierung (`after($id)`), Lesevorgänge für Zeiträume, das Überspringen von Segmenten im Log und eine stabile Sortierung überall.

```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);
```

Die Generierung ist innerhalb eines Prozesses monoton: IDs, die in derselben Millisekunde erstellt werden, erhöhen die vorherige Entropie, statt sie neu zu würfeln. So bleiben auch schnelle Schreibserien nach Erstellungsreihenfolge sortiert.

## Zeitliche Adressierung

Für Zeitfenster leitet storh die kleinstmögliche und die größtmögliche UUIDv7 für einen Millisekunden-Zeitstempel ab und vergleicht IDs mit diesen Grenzen:

```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);
```

Deshalb benötigen Lesevorgänge für Zeiträume kein Zeitstempelfeld in den Datensatzdaten: Die ID enthält den Erstellungszeitpunkt.

## Eigene IDs angeben

Alle Engines akzeptieren bei jedem Schreibvorgang eine explizite ID (`$docs->put($data, $id)`) sowie einen aufrufbaren `id_generator` in ihrem Konstruktor. IDs aus beiden Quellen werden als UUIDv7 überprüft, daher müssen benutzerdefinierte Generatoren solche IDs erzeugen. Mit deterministischen Generatoren erstellt die Testsuite reproduzierbare Testdaten. `UuidV7::reset_for_tests()` setzt den prozessweiten monotonen Zustand zwischen Testfällen zurück.
