Генератор ULID

Генерируйте сортируемые 26-символьные ULID (Crockford base32) и декодируйте встроенную метку времени обратно в дату. Отлично для первичных ключей БД.

Сортируемые уникальные идентификаторы. ULID состоит из 26 символов: первые 10 кодируют время создания в миллисекундах, последние 16 — случайные. Это делает их лексикографически сортируемыми и безопасными для использования в качестве ключей. Генерируется в браузере.

ULID против UUID

Что такое ULID

ULID — это 128-битный идентификатор, той же ширины, что UUID, разделённый на две части: 48-битная миллисекундная метка времени, за которой следуют 80 случайных бит. Он выводится как 26 символов Crockford base32, а не как 36-символьный гипененированный hex UUID, поэтому он короче, не зависит от регистра и свободен от символов, которые легче всего перепутать — I, L, O и U исключены из алфавита.

Существенная разница не в кодировке, а в порядке. Поскольку метка времени занимает старшие биты, а base32 сохраняет порядок байтов, сортировка ULID как обычных строк сортирует их по времени создания. Два ID, созданные в ту же миллисекунду, откатываются к своей случайной части, но между миллисекундами порядок точен.

Почему сортируемость важна для баз данных

UUIDv4 равномерно случаен — это именно то, что вам не нужно в кластеризованном индексе. Каждая вставка попадает в случайную точку B-дерева, поэтому база данных постоянно дробит страницы и обращается к холодным. Индекс растёт больше, чем нужно, а пропускная способность записи падает по мере роста таблицы. Это хорошо задокументированная проблема UUID-первичных ключей в InnoDB MySQL и в SQL Server.

Идентификатор, упорядоченный по времени, добавляется у правого края индекса — тот же шаблон доступа, что у автоинкрементного целого. Вы сохраняете преимущества глобально уникального ключа, сгенерированного клиентом, — без обращения за ID, без координации между сервисами, безопасное слияние между шардами, — без фрагментации индекса.

Когда использовать что-то другое

UUIDv7, стандартизированный в RFC 9562, делает то же, что ULID, в стандартном формате и раскладке UUID. Если ваш стек уже имеет нативные типы столбцов и инструменты UUID, UUIDv7 обычно лучший выбор сейчас просто потому, что он встраивается в существующую экосистему. ULID остаётся привлекательным, когда вы хотите более короткую, дружелюбную текстовую форму в URL или журналах.

В любом случае ясно: метка времени видима любому, у кого есть ID. Времена создания утечь, а соседние ID выдают порядок — не используйте их для чего-либо, где перечисление или время чувствительны. И при 80 случайных битах в миллисекунду коллизии не являются практической проблемой, но ULID — не секреты и никогда не должны использоваться как токены возможностей.

Примечание об открытом коде: реализовано с crypto.getRandomValues и самописным кодеком Crockford base32. Сторонних библиотек нет.

Часто задаваемые вопросы

Чем ULID отличается от UUID?
Оба по 128 бит, но ULID ставит 48-битную миллисекундную метку времени первой, поэтому сортировка строк сортирует по времени создания. UUIDv4 полностью случаен и сортируется произвольно.
Почему сортируемость важна для базы данных?
Случайные первичные ключи разбрасывают вставки по B-дереву и фрагментируют индекс. Ключи, упорядоченные по времени, добавляются ближе к концу, что сохраняет записи последовательными, а горячие страницы — маленькими.
Остаются ли упорядоченными ID, созданные в ту же миллисекунду?
В монотонном режиме — да. Вместо перерисовки случайной части инструмент увеличивает её, поэтому несколько ID, сгенерированных в одну миллисекунду, всё равно выходят по порядку.
Безопасно ли выставлять ULID публично?
Случайная половина непредсказуема, но метку времени может прочитать любой. Если время создания записи чувствительно, не используйте ULID как её публичный идентификатор.
Выбрать ULID или UUIDv7?
Они решают одну задачу. UUIDv7 стандартизирован в RFC 9562 и подходит под существующие столбцы и библиотеки UUID, поэтому для новой работы предпочтите его, если только вам конкретно не нужна 26-символьная форма Crockford.
Почему 26 символов?
128 бит, закодированных в Crockford Base32, требуют 26 символов. Алфавит исключает I, L, O и U, чтобы избежать и ошибок переписывания, и случайных слов.