AldeaCode Logo
Developer UUID vs ID autoincremental: qué clave primaria elegir
Developer 1 de mayo de 2026 AldeaCode Architecture

UUID vs ID autoincremental: qué clave primaria elegir

UUID vs ID entero autoincremental como clave primaria: rendimiento de índices, seguridad, distribución y la opción UUIDv7 en PostgreSQL y MySQL.

La elección que tu base de datos te obliga a hacer

Cuando diseñas una tabla, la clave primaria es la primera decisión que no se deshace fácil. ¿Entero auto incremental (1, 2, 3...) o UUID aleatorio (550e8400-e29b-41d4-a716-446655440000)?

La mayoría de tutoriales tiran al entero porque lleva más tiempo. La mayoría de startups modernas tiran al UUID porque suena más seguro. Los dos defaults están mal la mitad de las veces. La respuesta real depende de tres preguntas: cómo de grande crece tu conjunto de datos, quién ve los IDs, y si alguna vez combinas datos de varias bases.

De un vistazo

CaracterísticaEntero auto incrementalUUID (v4)
PredictibilidadSecuencial, fácil de adivinarAleatorio, opaco
Riesgo de colisiónNinguno en una sola BDPrácticamente cero, en cualquier sitio
Tamaño de índice4 u 8 bytes, B-tree compacto16 bytes, inserciones fragmentadas
Aspecto en URL/usuarios/4523/usuarios/550e8400-e29b-...
Cuándo elegirloBD única, IDs internosEscrituras distribuidas, URLs públicas

El caso a favor del entero

Los enteros auto incrementales son pequeños (4 u 8 bytes), se ordenan de forma natural, y casan perfecto con índices B-tree. Cuando insertas la fila 1001, va justo después de la 1000. El árbol apenas se mueve. El rendimiento se mantiene consistente con miles de millones de filas.

Los enteros también son legibles. “Usuario 4523” es fácil de hablar. “Usuario 550e8400-e29b-41d4-a716-446655440000” no. Los tickets de soporte, los logs y la salida de depuración se vuelven más legibles con enteros.

El entero es la elección correcta para:

  • Una sola aplicación hablando con una sola base de datos.
  • IDs internos que los usuarios no ven nunca.
  • Tablas de lookup con tamaño acotado.
  • Cualquier sitio donde puedas permitirte un punto de sincronización que reparte el siguiente id.

El entero es la elección incorrecta cuando:

  • Mezclas datos de dos bases de datos (los 1, 2, 3... chocan).
  • El ID se expone en URLs y no quieres que los usuarios adivinen los IDs de otros.
  • Distribuyes escrituras entre varios nodos (cada nodo necesitaría su propio rango de IDs).

El caso a favor del UUID

Los UUIDs son únicos sin coordinación. Genera uno en cualquier proceso, en cualquier máquina, en cualquier momento, y no chocará con otro. Esa propiedad es lo que los hace el default para sistemas distribuidos y para cualquier cosa donde el ID tiene que generarse antes de un round trip a la base de datos.

Los UUIDs también son inadivinables. Si tu URL es /pedidos/8af3-9c2e-..., un atacante no puede probar /pedidos/8af4-9c2e-... y encontrar el siguiente pedido. Los IDs enteros en URLs son una fuga de información (el conteo de pedidos, la tasa de altas nuevas, el orden temporal en que dos usuarios se registraron).

El UUID es la elección correcta para:

  • Sistemas distribuidos con escrituras desde varias fuentes.
  • IDs de cara al público en URLs y APIs.
  • Casos donde necesitas generar el ID antes de que la fila exista.
  • Sistemas multi tenant donde dos tenants podrían chocar en un contador serial.

El UUID es la elección incorrecta cuando:

  • Quieres inserts B-tree rápidos en un solo nodo (los UUIDs aleatorios destrozan el rendimiento del índice, ver abajo).
  • Quieres almacenamiento compacto (un UUID son 16 bytes contra 4 u 8 de un entero).
  • Quieres IDs de los que la gente pueda hablar (“usuario 4523” contra “usuario 550e8400-…”).

El problema del B-tree y el arreglo UUIDv7

Los UUIDs aleatorios destrozan el rendimiento de inserts porque los índices B-tree funcionan mejor cuando las entradas nuevas caen al final. Un ID entero nuevo siempre cae al final. Un UUID aleatorio nuevo cae en algún punto medio, y el árbol tiene que rebalancearse.

En producción, esto puede significar inserts de órdenes de magnitud más lentos en una tabla muy usada. La brecha de rendimiento aparece sobre los 10 millones de filas y sigue creciendo.

UUIDv7 lo arregla codificando el timestamp actual al inicio del UUID. Dos UUIDs v7 generados cerca en el tiempo empiezan con bytes parecidos, así que caen cerca en el índice. El rendimiento es comparable al de los enteros para cargas típicas.

Si estás tirando de UUID en 2026 y tu base de datos tiene soporte para UUIDv7 (PostgreSQL 18+, MySQL moderno, SQL Server moderno), usa v7 por defecto. Usa v4 solo cuando necesites específicamente que sea inadivinable y puedas asumir el coste del índice. El generador de UUIDs de AldeaCode genera v4 y v7 en lote, en tu navegador, sin subida.

Un árbol de decisión práctico

Un solo backend, una sola base de datos, IDs internos: entero.

IDs de cara al público en URLs, un solo backend: UUID v7. Ordenable por tiempo, difícil de adivinar.

Escrituras multi nodo, sistema distribuido: UUID v7 con el id de nodo codificado en los bits altos, o ULID. Coordinación local, sin choques globales.

Multi tenant donde los tenants no deben ver datos del otro: UUID v7 más una comprobación estricta de acceso. La inadivinabilidad es defensa en profundidad, no el control de acceso en sí.

IDs numéricos que tienes que mantener pero quieres ofuscar en URLs: guarda el entero en la base, expone un slug hasheado en URLs, descodifica en el controlador.

Migrar es más fácil de lo que parece

Si arrancaste con enteros y ahora necesitas UUIDs (una historia de crecimiento común), la migración es incremental. Añade una columna UUID al lado de la entera. Rellénala para las filas existentes. Pasa el código nuevo a usar el UUID. Quita la columna entera cuando nada la lea.

Lo contrario (de UUID a entero) es raro y más difícil, porque tienes que elegir cómo mapear UUIDs viejos a enteros nuevos de forma que preserve cualquier referencia externa.

Cuando necesites inspeccionar el formato de un UUID (qué versión, qué dice el timestamp), el generador de UUIDs, el convertidor de timestamps y el generador de hash de AldeaCode manejan los casos comunes. La elección de la clave primaria es una de esas decisiones que te paga o te castiga durante años. Elige a propósito, no por costumbre.

Lo que hacemos

Webs honestas, sin atajos.

Ingeniería real y diseño cuidado. Si te ha gustado el post, hablemos del tuyo.

Hablemos →

Te puede interesar

Ver todos los artículos →