Ulid
ULID
Un ULID (Universally Unique Lexicographically Sortable Identifier) es un identificador único diseñado para ser tanto globalmente único como lexicográficamente ordenado. Fue introducido como una alternativa a los UUID (Universally Unique Identifier), con la ventaja adicional de ser más legible y adecuado para sistemas que necesitan ordenación temporal.
Estructura de un ULID
Un ULID tiene una longitud fija de 26 caracteres alfanuméricos y está formado por dos partes:
- Timestamp (48 bits):
- Representa un tiempo en milisegundos desde el Unix epoch (1 de enero de 1970).
- Se almacena como los primeros 10 caracteres en el formato base32 (alfabeto Crockford).
- Esto permite que los ULID sean lexicográficamente ordenados por tiempo.
- Randomness (80 bits):
- Consiste en 16 caracteres generados aleatoriamente también en base32.
- Garantiza que los ULID sean únicos incluso cuando se generan múltiples en el mismo milisegundo.
Características principales
- Orden lexicográfico:
- Gracias a la parte de tiempo, los ULID se ordenan naturalmente por momento de creación.
- Esto es útil para sistemas donde el orden cronológico es importante, como bases de datos o logs.
- Legibilidad:
- Al usar base32, los ULID evitan caracteres ambiguos como “I” y “l” (i mayúscula y ele minúscula) o “O” y “0” (O mayúscula y cero), lo que facilita su lectura.
- Compatibilidad con UUID:
- Aunque tienen un formato distinto, se pueden usar como reemplazo en la mayoría de los sistemas que soportan UUID.
Ejemplo de ULID
Un ULID típico podría verse así:
01H8K72J27T9A2P03C1P5X3VYV
- Los primeros 10 caracteres (
01H8K72J27) representan el tiempo. - Los últimos 16 caracteres (
T9A2P03C1P5X3VYV) son la parte aleatoria.
Ventajas sobre UUID
- Ordenación natural por tiempo.
- Más legible debido al uso de base32.
- Más corto (26 caracteres frente a 36 en un UUID en su representación estándar).
La razón por la cual sabemos que los primeros 10 caracteres de un ULID representan el timestamp y los siguientes 16 son aleatorios proviene de la especificación formal de los ULIDs y del desglose técnico de cómo están construidos. Aquí está la explicación en detalle:
Especificación Técnica de ULID
Un ULID está compuesto de 128 bits (16 bytes), divididos en dos partes:
- 48 bits para el Timestamp:
- Los 48 bits (6 bytes) iniciales representan el tiempo en milisegundos desde el Unix epoch.
- Al codificar estos 48 bits en base32, se generan exactamente 10 caracteres alfanuméricos.
- 80 bits para la Aleatoriedad:
- Los 80 bits restantes (10 bytes) son generados aleatoriamente.
- Cuando se codifican en base32, estos bits producen 16 caracteres alfanuméricos.
Cálculo Detallado
-
Timestamp (48 bits):
-
48 bits = 248, lo que permite representar hasta 281.5 billones de milisegundos desde el Unix epoch.
2482^{48}
-
Esto cubre un rango de tiempo suficiente (aproximadamente hasta el año 10889).
-
Los 48 bits se dividen en grupos de 5 bits (porque base32 usa bloques de 5 bits por carácter), resultando en 48÷5=9.6, que se redondea a 10 caracteres.
48÷5=9.648 \div 5 = 9.6
-
-
Aleatoriedad (80 bits):
-
80 bits = 280, lo que da un espacio masivo para generar valores únicos incluso si varios ULIDs se crean en el mismo milisegundo.
2802^{80}
-
Al dividir 80 bits en bloques de 5 bits, obtenemos 80÷5=16, lo que resulta en 16 caracteres.
80÷5=1680 \div 5 = 16
-
Ejemplo Visual de la Estructura
Tomemos este ULID como ejemplo:
01H8K72J27T9A2P03C1P5X3VYV
-
Primera parte (10 caracteres):
01H8K72J27Esto representa el timestamp. Estos caracteres corresponden a los primeros 48 bits que indican el tiempo de creación.
-
Segunda parte (16 caracteres):
T9A2P03C1P5X3VYVEsta es la parte aleatoria, generada para garantizar unicidad en un mismo milisegundo.