Timestamp-first COMB Codec

Version 4, random UUIDs are doubly problematic when it comes to sorting and storing to databases (see Insertion Order and Sorting), since their values are random, and there is no timestamp associated with them that may be rearranged, like with the ordered-time codec. In 2002, Jimmy Nilsson recognized this problem with random UUIDs and proposed a solution he called “COMBs” (see “The Cost of GUIDs as Primary Keys”).

So-called because they combine random bytes with a timestamp, the timestamp-first COMB codec replaces the first 48 bits of a version 4, random UUID with a Unix timestamp and microseconds, creating an identifier that can be sorted by creation time. These UUIDs are monotonically increasing, each one coming after the previously-created one, in a proper sort order.

Use the timestamp-first COMB codec to generate a version 4 UUID
use Ramsey\Uuid\Codec\TimestampFirstCombCodec;
use Ramsey\Uuid\Generator\CombGenerator;
use Ramsey\Uuid\UuidFactory;

$factory = new UuidFactory();
$codec = new TimestampFirstCombCodec($factory->getUuidBuilder());

$factory->setCodec($codec);

$factory->setRandomGenerator(new CombGenerator(
    $factory->getRandomGenerator(),
    $factory->getNumberConverter()
));

$timestampFirstComb = $factory->uuid4();

printf(
    "UUID: %s\nVersion: %d\nBytes: %s\n",
    $timestampFirstComb->toString(),
    $timestampFirstComb->getFields()->getVersion(),
    bin2hex($timestampFirstComb->getBytes())
);

This will use the timestamp-first COMB codec to generate a version 4 UUID with the timestamp replacing the first 48 bits and will print out details about the UUID similar to these:

UUID: 9009ebcc-cd99-4b5f-90cf-9155607d2de9
Version: 4
Bytes: 9009ebcccd994b5f90cf9155607d2de9

Note that the bytes are in the same order as the string representation. Unlike the ordered-time codec, the timestamp-first COMB codec affects both the string representation and the byte representation. This means either the string UUID or the bytes may be stored to a datastore and sorted. To learn more, see Using In a Database.