Saltar al contenido
AldeaCode Logo
Generador UUID / PostgreSQL Generadores 100% local

Generar UUIDs en PostgreSQL: gen_random_uuid y uuid-ossp

PostgreSQL ha tenido dos rutas para generar UUIDs durante años: la histórica extensión uuid-ossp y la moderna gen_random_uuid integrada en pgcrypto. Elige la nueva y olvídate.

gen_random_uuid es la respuesta en PostgreSQL 13+

Desde PostgreSQL 13, gen_random_uuid() está disponible sin necesidad de extensión. Genera un UUIDv4 (aleatorio) conforme con RFC 9562 y es exactamente lo que quieres para claves primarias en el 99% de los casos.

CREATE TABLE orders (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  amount NUMERIC NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

Si estás en PostgreSQL 12 o anterior, dos opciones: actualizar, o activar pgcrypto con CREATE EXTENSION IF NOT EXISTS pgcrypto; para tener la misma función. Las dos rutas hacen lo mismo.

uuid-ossp es legacy. No lo uses.

uuid-ossp es la extensión histórica que te daba uuid_generate_v4(), uuid_generate_v1() y compañía. No está deprecada oficialmente pero los propios mantenedores recomiendan gen_random_uuid() para proyectos nuevos. El RNG interno de pgcrypto es mejor, y la huella de dependencia es menor.

Si tienes un schema existente usando uuid_generate_v4(), déjalo en paz. Migrar columnas es peligroso y la función funciona bien. Tablas nuevas: usa gen_random_uuid().

UUIDv7 si te importa la localidad del índice

Los UUIDs aleatorios son nefastos para índices B-tree porque cada insert cae en una página random. Los setups modernos de Postgres con volumen alto de inserts usan UUIDv7, que prefija un timestamp de milisegundos y deja los inserts append-only.

PostgreSQL aún no trae generador UUIDv7 nativo (a fecha de v17). O instalas una extensión tipo pg_uuidv7, o generas UUIDv7 en tu aplicación e INSERTAS como valores UUID normales. La comunidad Postgres lo está tracking pero no ha aterrizado todavía.

Notas de rendimiento y almacenamiento

Una columna UUID ocupa 16 bytes en disco, exactamente el doble que un BIGINT. El impacto en un SELECT de una sola tabla es invisible. El impacto en un schema con muchos JOINs y cientos de millones de filas es real pero pequeño. El impacto en localidad de caché con UUIDv4 aleatorio es mayor que ambos.

Si estás haciendo JOIN sobre 4 tablas con UUIDs y mediste regresión, UUIDv7 lo arregla. Si no has medido nada, quédate con gen_random_uuid() y haz ship.

Ejemplo completo

sql
-- Uno suelto
SELECT gen_random_uuid();
-- → 1a2b3c4d-5e6f-4a8b-9c0d-1e2f3a4b5c6d

-- Default para clave primaria
CREATE TABLE orders (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  amount NUMERIC NOT NULL,
  created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);

-- En lote: 1000 UUIDs frescos
SELECT gen_random_uuid()
FROM generate_series(1, 1000);

-- Si estás antes de 13: activa pgcrypto primero
CREATE EXTENSION IF NOT EXISTS pgcrypto;

¿Solo necesitas el resultado?

Cuando necesitas un UUID fuera de Postgres, tipo poblar una migración o pegar en un YAML, el generador online en el navegador te da el mismo valor conforme con RFC 9562 usando la Web Crypto API y sin viaje al servidor.

Abrir Generador de UUID v4 →

Preguntas frecuentes

¿Necesito alguna extensión para gen_random_uuid en PostgreSQL 13+?

No. Desde 13 está en el core. En 12 y anteriores necesitas pgcrypto. uuid-ossp es una extensión separada y antigua, no la necesitas para v4.

¿Cuántos UUIDs puedo generar antes de una colisión realista?

UUIDv4 tiene 122 bits de entropía. Necesitarías generar unos 2.71 trillones de UUIDs para alcanzar un 50% de probabilidad de colisión. Para cualquier carga real, trata las colisiones como imposibles.

¿Puedo usar UUIDs como clave primaria en cualquier tabla sin pensar?

Casi. La excepción son tablas time-series enormes con inserts constantes donde UUIDv4 destruye la localidad del índice. Allí cambias a UUIDv7 o te quedas con bigserial. Para el 99% de tablas UUIDv4 vale.