UUID vs ULID: elegir identificadores para tu aplicación
UUID v4 frente a v7, estructura y ordenabilidad de ULID, qué hacen los identificadores aleatorios a un índice B-tree, probabilidad de colisión, exposición en URL y generación local de identificadores.
Qué debe hacer un identificador de aplicación
Un identificador generado tiene un trabajo—ser único—más unos cuantos que recoge por el camino: generarse en cualquier parte sin coordinación, almacenarse compacto, ordenarse de forma predecible y no filtrar nada embarazoso. UUID y ULID superan el listón de la unicidad; difieren en todo lo demás.
- Sin coordinaciónGeneración descentralizada: cualquier servicio, worker o pestaña de navegador puede acuñar un identificador sin preguntar a un contador central, que es lo que hace a ambos formatos aptos para sistemas distribuidos.
- Los mismos 128 bits128 bits en ambos casos: un UUID es un valor de 128 bits escrito como 36 caracteres hexadecimales con guiones; un ULID lleva los mismos 128 bits como 26 caracteres base32.
- La disposición es la diferenciaLa verdadera pregunta es la disposición: qué bits son aleatorios y cuáles codifican tiempo decide cómo se comporta el identificador en un índice y qué revela.
Versiones UUID: v4 es aleatoria, v7 ordenada por tiempo
RFC 9562 define varias versiones de UUID, pero dos dominan el trabajo de aplicaciones. La versión 4 llena 122 de los 128 bits con aleatoriedad y no incrusta nada más; la versión 7 abre con una marca de tiempo Unix de 48 bits en milisegundos y llena los 74 bits restantes con aleatoriedad.
- v4: aleatorio purov4 es la opción de privacidad máxima: el valor no dice nada sobre cuándo ni dónde se hizo, y 122 bits aleatorios son más unicidad de la que cualquier aplicación gastará jamás.
- v7: el tiempo primerov7 se ordena principalmente por su marca temporal en milisegundos. El orden dentro del mismo milisegundo y entre dispositivos depende del generador y del comportamiento del reloj.
- Salta v1Las versiones antiguas son herencia: v1 incrustaba una dirección MAC y un valor de reloj, filtrando ambos; v3 y v5 son hashes basados en nombre para derivar ID estables, no aleatoriedad fresca.
ULID: ordenable y compacto como texto
Un ULID son 26 caracteres de base32 Crockford: los primeros 10 caracteres codifican una marca de tiempo de milisegundos de 48 bits, los 16 restantes codifican 80 bits aleatorios. El alfabeto excluye deliberadamente I, L, O y U, así que los identificadores sobreviven a ser leídos en voz alta o tecleados desde una captura.
- Orden de cadena = orden temporalEl orden lexicográfico es el orden temporal: ordenar ULID como cadenas planas los ordena por tiempo de creación sin parsear—útil en líneas de log, nombres de archivo y almacenes clave-valor.
- 26 caracteres segurosCompacto y seguro en URL: 26 caracteres sin distinción de mayúsculas, sin guiones ni símbolos, más corto que los 36 de un UUID y seguro en cualquier segmento de ruta o parámetro de consulta.
- Monótono por milisegundoDentro de un milisegundo, el orden viene de la parte aleatoria; los generadores que la incrementan monótonamente—como el generador por lotes de Toolars—mantienen incluso los identificadores del mismo milisegundo en orden de generación.
Los ID aleatorios fragmentan tus índices
Un índice B-tree está ordenado, e insertar un UUID v4 aleatorio escribe en una hoja aleatoria cada vez: las páginas se dividen, la caché de búfer se agita y el índice se hincha con espacio muerto. Los identificadores ordenados por tiempo se anexan cerca del borde derecho del índice, convirtiendo las inserciones en el mejor caso del B-tree.
Por eso la elección pertenece al momento de diseñar el esquema, no después del primer trimestre lento: migrar una clave primaria significa reescribir cada fila y cada clave foránea que la referencia. Si la tabla siempre será pequeña, el desorden de v4 nunca se hace visible; si crecerá a cientos de millones de filas bajo escritura constante, los formatos ordenados pagan su renta desde el primer día.
- Lo aleatorio dispersaCon v4 como clave primaria, las tablas de inserción intensa muestran más divisiones de página, factores de llenado menores y un rendimiento de escritura mediblemente peor que con una clave ordenada del mismo tamaño.
- Lo ordenado anexav7 y ULID mejoran la localidad del índice sin dejar de generarse de forma descentralizada. Los ID contiguos de un lote monótono pueden ser previsibles; aplica la autorización con independencia del identificador.
- Mide el costeEl coste es real pero modesto: 128 bits son el doble del almacenamiento de un bigint, y las claves ordenadas por tiempo concentran las escrituras del día en el borde derecho del índice, lo que solo importa a tasas de inserción muy altas.
Colisiones, URL y lo que un ID revela
Primero, las probabilidades de colisión: con 122 bits aleatorios independientes en v4, mil millones de identificadores tienen una probabilidad de colisión de aproximadamente una entre 10^19. Los 80 bits aleatorios de ULID cubren otro escenario: identificadores creados en el mismo milisegundo.
Pega cualquier valor sospechoso en el validador: reconoce la forma canónica de UUID de 36 caracteres con su variante RFC 9562 y su nibble de versión, el alfabeto ULID de 26 caracteres con su regla de desbordamiento, y reporta la marca de tiempo incrustada para los formatos ordenados por tiempo—así que un valor de un log te dice qué es antes de que construyas sobre él.
- Probabilidad despreciableNingún formato es una frontera de seguridad: un identificador en una URL vale para direccionar, pero cualquiera que lo vea puede citarlo—la autorización debe venir de comprobaciones de acceso, no de la opacidad del ID.
- Los ID no son secretosv7 y ULID filtran el tiempo de creación por diseño; el validador lo extrae abiertamente. Normalmente es metadato inofensivo, pero decídelo conscientemente para objetos de cara al público.
- El tiempo es visibleLos ID secuenciales de base de datos filtran volumen y ritmo de crecimiento; los identificadores aleatorios y tiempo-más-aleatorio no revelan nada sobre cuántos registros existen.
Genera y valida sin servidor
La generación de identificadores necesita exactamente un recurso escaso—buena aleatoriedad—y el navegador ya la tiene. El área toma de crypto.getRandomValues, genera lotes enteramente en la pestaña y nunca transmite un valor.
- 1–100 por loteElige UUID v4, UUID v7 o ULID y genera de 1 a 100 por lote; los lotes v7 y ULID incrementan el campo aleatorio monótonamente, así que todo el lote queda en orden de generación.
- Mayúsculas y exportaciónLas mayúsculas de salida son una elección de presentación: canónico, mayúsculas o minúsculas, con copiar-todo más descargas de texto por líneas y CSV que registran el tiempo incrustado de cada identificador.
- Validación instantáneaLa validación responde al instante preguntas de estructura: longitud, alfabeto, versión y variante UUID, valores especiales nil y max, desbordamiento ULID y la marca de tiempo incrustada en UTC.
Preguntas frecuentes
¿Debo usar UUID v4 o v7 como claves primarias de la base de datos?
¿Qué puede aprender alguien de mis identificadores?
¿Qué probabilidad real hay de colisión de un UUID?
ULID es base32; tus tokens probablemente son Base64.
Las codificaciones de bytes a texto están debajo de cada identificador y token—aprende lo que cuestan y dónde se ganan su lugar.