03 / GUÍAS
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 por tiempo de creación con precisión de milisegundos, así que los identificadores generados después se ordenan tras los anteriores—la propiedad que las bases de datos quieren de una clave primaria.
- 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 restauran la localidad manteniendo la generación descentralizada—sin secuencia, sin coordinación y aún sin predicción de los ID de otras filas.
- 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 la matemática de colisiones: con 122 bits aleatorios en v4, generar mil millones de identificadores deja una probabilidad de colisión cercana a una entre 10^18—efectivamente nunca. Los 80 bits aleatorios de ULID protegen un presupuesto distinto: los identificadores creados dentro del 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.
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.