mediagone / small-uid
Small Unique Identifier - Quite like an ULID, but half smaller (64 bits).
Requires
- php-64bit: ^7.4|^8.0
- ext-gmp: *
- mediagone/types-common: ^0.5.1|^0.6|^0.7
Requires (Dev)
- phpunit/phpunit: ^9.0
README
⚠️ This project is in experimental phase, the API may may be subject to change.
UUIDs are frequently used as database Primary Key in software development. However, they aren't the best choice mainly due to their random sorting and the resulting fragmentation in databases indexes.
Using ULIDs is generally a very good alternative, solving most of UUID flaws.
Small UIDs are also an ideal alternative when you do not need as much uniqueness and want shorter "user-friendly" encoded strings.
Summary:
- Installation
- Usages
- License
Introduction
Small UIDs are short unique identifiers especially designed to be used as efficient database Primary Key:
- Half smaller than UUID / ULID (64-bit)
- Lexicographically sortable
- Encodable as a short user-friendly and URL-safe base-62 string (
a-zA-Z0-9
) - User-friendly strings are generated in a way to be always very different (no shared prefix due to similar timestamps)
* the Uid includes a timestamp, so collisions may occur only during the same millisecond.
** monotonic sort order, but random order when generated at the same millisecond.
*** theorical number of generated Uids before the first expected collision.
They are internally stored as 64-bit integers (44-bit timestamp followed by 20 random bits):
|-----------------------| |------------|
Timestamp Randomness
44 bits 20 bits
The random number suffix still guarantees a decent amount of uniqueness when many ids are created in the same millisecond (up to 1,048,576 different values) and you may only expect collision if you're generating more than 1024 random ids during the same millisecond.
Sorting
Because of the sequential timestamp, Small UIDs are naturally sorted chronologically. It improves indexing when inserting values in databases, new ids being appended to the end of the table without reshuffling existing data (read more in this article).
However, sort order within the same millisecond is not guaranteed because of the random bits suffix.
Installation
This package requires PHP (64-bit) 7.4+ and GMP extension.
Add it as Composer dependency:
$ composer require mediagone/small-uid
If you're using Doctrine ORM, you'll probably want to install also appropriate custom types:
$ composer require mediagone/small-uid-doctrine
Usages
Creation
Most useful way to generate an Uid is the random()
static factory method, which creates a new random Uid using the current timestamp and a random suffix:
$uid = SmallUid::random();
You can also generate an Uid from a 16-chars long hexadecimal string:
$uid = SmallUid::fromHex('1234567890abcdef');
You can also generate an Uid from a base62-encoded string using fromString
method, but this will detailed in the next section.
$uid = SmallUid::fromString('LscmjzUyKLR');
In some cases, you may need a null-object Uid, therefore there is a special static factory method:
$uid = SmallUid::nil();
Short-string representation
Using the hexadecimal representation is not always convenient (eg. for use in URLs), hopefully it can be safely converted back and forth to a base-62 string, which is only 10 or 11-chars long (depending on the Uid's internal value).
To get an uid's short-string representation, just cast it to a string:
$uid = SmallUid::fromHex('1234567890abcdef'); (string)$uid; // string(11) "LscmjzUyKLR"
To convert back the short-string to an Uid instance, use the fromString()
static factory method:
$uid = SmallUid::fromString('LscmjzUyKLR');
Serialization
You serialize your Uids using their hexadecimal representation (which is always a 16-chars long hexadecimal string):
$uid = SmallUid::fromString('LscmjzUyKLR'); (string)$uid->getHex(); // string(16) "1234567890abcdef"
Uids can also be converted to an 8-bit integer or a binary string (eg. for database persistence):
$uid = SmallUid::fromString('LscmjzUyKLR'); (string)$uid->toHex()->toDecimal(); // int(1311768467294899695) (string)$uid->toHex()->toHex()->toBinary(); // string(8) "4Vx" (binary string)
Retrieving creation DateTime
Every Uid embeds a timestamp reflecting its creation datetime:
$uid = SmallUid::fromHex('1234567890abcdef'); $datetime = $uid->getCreationDatetime(); // retrieve Uid's creation datetime (string)$creationDatetime; // "2009-08-23T03:58:16+00:00"
License
Small UID is licensed under MIT license. See LICENSE file.