UUID vs GUID: qué es un UUID, versiones (v4, v7) y el orden de bytes que rompe migraciones
UUID y GUID son, a efectos prácticos, lo mismo: un identificador de 128 bits escrito como 32 dígitos hexadecimales en grupos 8-4-4-4-12. UUID (Universally Unique Identifier) es el nombre del estándar; GUID (Globally Unique Identifier) es el nombre que usa Microsoft. La diferencia que sí importa aparece al guardarlos en binario, donde Windows y .NET ordenan algunos bytes al revés, y es la causa de muchos IDs «corruptos» al migrar entre SQL Server y otras bases de datos.
Mismo formato, distinto nombre
550e8400-e29b-41d4-a716-446655440000 UUID (minúsculas, forma habitual)
{550E8400-E29B-41D4-A716-446655440000} GUID como suele mostrarlo Windows
└──┬───┘ └┬─┘ └┬─┘ └┬─┘ └────┬─────┘
8 4 4 4 12 dígitos hexadecimales = 128 bits
El estándar actual es RFC 9562 (2024), que sustituye a RFC 4122. Microsoft implementó el mismo formato bajo el nombre GUID en COM y Windows, y .NET lo expone como System.Guid. Las mayúsculas y las llaves son solo presentación: {550E8400-…} y 550e8400-… son el mismo valor, y la comparación debe ignorar mayúsculas.
Dentro del UUID hay dos campos fijos. El primer dígito del tercer grupo es la versión (el 4 de 41d4), y los primeros bits del cuarto grupo indican la variante (a en a716, que corresponde a RFC 4122/9562). Por eso un UUID v4 siempre tiene un 4 en esa posición y un 8, 9, a o b al inicio del cuarto grupo.
La diferencia real: el orden de los bytes
En texto, UUID y GUID son idénticos. En binario, no siempre. La estructura GUID de Microsoft guarda los tres primeros campos en orden little-endian, y Guid.ToByteArray() en .NET los devuelve así. El estándar UUID usa big-endian en todo el valor.
texto: 00112233-4455-6677-8899-aabbccddeeff
bytes UUID: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff (RFC 9562, big-endian)
bytes GUID: 33 22 11 00 55 44 77 66 88 99 aa bb cc dd ee ff (Guid.ToByteArray)
Si copias un uniqueidentifier de SQL Server como 16 bytes a una columna BINARY(16) de MySQL o a otro sistema, y luego lo conviertes a texto con las reglas estándar, obtienes un UUID distinto: los primeros 8 bytes aparecen desordenados. El valor no está corrupto, solo se interpretó con otro orden. Migra siempre por la representación en texto, o convierte explícitamente. En Python, uuid.UUID(bytes_le=…) lee el formato de Microsoft.
SQL Server también ordena los uniqueidentifier de forma peculiar: compara primero los últimos 6 bytes. Por eso NEWSEQUENTIALID() genera valores que solo son secuenciales para SQL Server, no al ordenarlos como texto en otra base de datos.
Las versiones que vas a encontrar
v1 fecha + dirección MAC expone cuándo y en qué máquina se generó
v3 hash MD5 de un nombre determinista: mismo nombre -> mismo UUID
v4 aleatorio (122 bits) el más usado hoy
v5 hash SHA-1 de un nombre como v3, pero con SHA-1
v6 v1 reordenado ordenable por tiempo; para sistemas que ya usan v1
v7 milisegundos Unix + aleatorio ordenable por tiempo; recomendado para claves nuevas
v8 formato libre para esquemas propios
v4 es el valor por defecto de crypto.randomUUID(), uuid.uuid4() y Guid.NewGuid(). Con 122 bits aleatorios, la probabilidad de colisión es despreciable: harían falta del orden de 2,7 trillones (2,7 × 10¹⁸) de UUIDs para tener un 50% de probabilidad de una sola coincidencia.
v7, definido en RFC 9562, empieza con la marca de tiempo en milisegundos. Los valores generados después son mayores al ordenarlos, lo que resuelve el principal problema de v4 como clave primaria.
UUID como clave primaria: v4 frente a v7
Los UUID permiten generar IDs en el cliente o en varios servidores sin coordinarse, y no revelan cuántos registros hay, al contrario que un autoincremental 1, 2, 3. El coste está en los índices. Un v4 aleatorio inserta cada fila en un punto al azar del índice B-tree, lo que provoca divisiones de páginas, más escritura y peor uso de la caché cuando la tabla es grande.
Un v7 inserta casi siempre al final del índice, como un autoincremental, y conserva las ventajas de los UUID. Para tablas nuevas es la mejor opción por defecto. Ten en cuenta que su prefijo revela el momento de creación del registro, lo que en algunos casos puede ser información sensible.
Guárdalos con el tipo nativo cuando exista: uuid en PostgreSQL (16 bytes), uniqueidentifier en SQL Server o BINARY(16) en MySQL con UUID_TO_BIN() y BIN_TO_UUID(). Guardarlos como CHAR(36) ocupa más del doble y hace los índices más lentos.
Cómo generar UUIDs
// JavaScript (navegador en contexto seguro, y Node.js)
crypto.randomUUID(); // v4
# Python
import uuid
uuid.uuid4()
uuid.uuid7() # Python 3.14+
// C# / .NET
Guid.NewGuid(); // v4
Guid.CreateVersion7(); // .NET 9+
-- PostgreSQL
SELECT gen_random_uuid(); -- v4 (PostgreSQL 13+)
SELECT uuidv7(); -- PostgreSQL 18+
-- SQL Server
SELECT NEWID(); -- v4
No construyas UUIDs con Math.random() ni concatenando marcas de tiempo. Los generadores de las librerías usan una fuente aleatoria criptográficamente segura, que es lo que hace que las colisiones sean improbables en la práctica.
Fuentes y lecturas recomendadas
RFC 9562 (Universally Unique IDentifiers) define el formato, las versiones 1 a 8 y la variante, y sustituye a RFC 4122. La documentación de Microsoft sobre System.Guid describe ToByteArray() y CreateVersion7(), y la de SQL Server describe uniqueidentifier y NEWSEQUENTIALID(). La documentación de Python (uuid) y de PostgreSQL (funciones UUID) cubre bytes_le, uuid7(), gen_random_uuid() y uuidv7().
Frequently asked questions
¿Cuál es la diferencia entre UUID y GUID?
Ninguna en el formato ni en el texto: ambos son identificadores de 128 bits con forma 8-4-4-4-12. GUID es el nombre de Microsoft para UUID. La única diferencia práctica es que el GUID de Microsoft guarda los tres primeros campos en little-endian cuando se representa en bytes.
¿Un GUID generado en .NET es un UUID válido?
Sí. `Guid.NewGuid()` genera un UUID versión 4 estándar. Solo hay que tener cuidado al convertirlo a bytes con `ToByteArray()`, que usa el orden de Microsoft.
¿Qué versión de UUID debo usar?
v4 para identificadores aleatorios en general, y v7 para claves primarias de bases de datos, porque es ordenable por tiempo y mantiene los índices compactos. v3 y v5 sirven cuando necesitas el mismo UUID para el mismo nombre.
¿Pueden repetirse dos UUID?
En teoría sí, en la práctica no con un generador correcto. Con los 122 bits aleatorios de v4 harían falta unos 2,7 × 10¹⁸ UUIDs para tener un 50% de probabilidad de una colisión.
¿Por qué mis GUIDs cambian al migrar de SQL Server a otra base de datos?
Porque se copiaron como bytes y SQL Server usa el orden de bytes de Microsoft en los tres primeros campos. Migra usando la representación en texto o convierte el orden de bytes explícitamente.
¿Los UUID distinguen mayúsculas y minúsculas?
No. `550E8400-…` y `550e8400-…` son el mismo UUID. El estándar recomienda generar en minúsculas y comparar sin distinguir mayúsculas.