Sobre usar PostgreSQL y UUID como clave primaria
(maciejwalkowiak.com)- Los UUID se usan con frecuencia como clave primaria en tablas de bases de datos
- Son fáciles de generar, fáciles de compartir entre sistemas distribuidos y garantizan unicidad
- Considerando el tamaño de un UUID, uno podría preguntarse si esta es la elección correcta, pero muchas veces no podemos decidirlo
- Este artículo no se centra en si “UUID es un formato adecuado para una clave”, sino en cómo usar de manera eficiente UUID como clave primaria en PostgreSQL
Usar PostgreSQL y UUID como clave primaria
- ¿Qué es un UUID?
- Los UUID se usan con frecuencia como clave primaria de tablas de bases de datos
- Se pueden compartir fácilmente entre sistemas distribuidos y garantizan unicidad
- Por el tamaño de los UUID, puede surgir la duda de si son adecuados, pero muchas veces no hay alternativa
Tipo de dato UUID en PostgreSQL
-
Guardar UUID como cadena
- PostgreSQL ofrece el tipo de dato
textpara almacenar cadenas - Sin embargo, el tipo
textno es adecuado para almacenar UUID - PostgreSQL ofrece el tipo de dato dedicado
uuidpara UUID - El tipo
uuides un tipo de dato de 128 bits, y requiere 16 bytes para almacenar un valor - El tipo
textagrega una sobrecarga de 1 o 4 bytes
- PostgreSQL ofrece el tipo de dato
-
Resultados del experimento
- Se crearon dos tablas para comparar: una con tipo
texty otra con tipouuid - Después de insertar 10,000,000 de filas, se comparó el tamaño de las tablas y de los índices
- La tabla que usa tipo
textes 54% más grande y el tamaño del índice es 85% mayor
- Se crearon dos tablas para comparar: una con tipo
UUID y los índices B-Tree
-
Índices B-Tree y UUID
- Los UUID aleatorios no son adecuados para índices B-Tree
- Los índices B-Tree funcionan bien con valores ordenados
UUID.randomUUID()de Java devuelve UUID v4, que es un valor seudoaleatorio- UUID v7 genera valores ordenados por tiempo, por lo que es adecuado para índices B-Tree
-
Uso de UUID v7
- Para usar UUID v7 en Java se necesita la librería
java-uuid-generator - Generar UUID v7 puede mejorar el rendimiento de inserción
- Para usar UUID v7 en Java se necesita la librería
Impacto de UUID v7 en el rendimiento de INSERT
- Experimento
- Se creó una tabla que usa UUID v7 y se insertaron 10,000 filas 10 veces para medir el rendimiento
- Los resultados son algo aleatorios, pero insertar UUID v7 es aproximadamente 2 veces más rápido
Lecturas adicionales
- Es posible que PostgreSQL 17 admita UUID v7 de forma nativa
- Información sobre el formato UUID v7
- El impacto de UUID en el rendimiento como clave primaria de base de datos
Resumen
-
Problema de la longitud de UUID
- Incluso con optimización, UUID no es el tipo más óptimo como clave primaria
- Si hay libertad de elección, conviene considerar otras opciones como TSID
-
Necesidad de optimización
- Si se esperan conjuntos de datos grandes o alto tráfico, vale la pena considerar optimización
- Cambiar la clave primaria es una tarea difícil, así que es importante configurarla correctamente desde el inicio
-
Precauciones
- El autor no es un experto en PostgreSQL; solo comparte lo que aprendió
- Si te resultó útil, agradecerá comentarios o feedback por Twitter
Resumen de GN⁺
- Este artículo trata sobre formas eficientes de usar UUID como clave primaria en PostgreSQL
- Muestra mediante experimentos que usar UUID v7 puede mejorar el rendimiento de inserción
- Si se esperan conjuntos de datos grandes o alto tráfico, hace falta optimización
- También vale la pena considerar otras opciones como TSID
4 comentarios
¿Es demasiado pedir una codificación base62 para
uuiden lugar del formato estándar (hexadecimal + guiones)?uuidv7 es invencible
uuidv8+ es un "dios"
El mayor obstáculo es que no es amigable para las personas... Yo todavía necesito bastante esa parte en muchos casos..
Opiniones de Hacker News
Se recomienda usar
bigserialcomo clave primaria amigable con B-tree, y considerar UUID codificados como cadena como opción de localizador de registros externoshashids; no tiene calidad criptográfica y no resulta familiar para la gente comúnAl diseñar el esquema de una base de datos, tener presentes los principios de separación de responsabilidades y simpatía mecánica
Los IDs aleatorios tipados de Stripe en realidad no son aleatorios
bigserial+HMACcifrado con AES y codificado en base58En Postgres, los UUID aleatorios no son un gran problema
serial(4 bytes) obigserial(8 bytes), pero a nivel de tabla completa no es un problema importanteAntes de considerar
serialvs. UUID aleatorio vs. UUID ordenado en Postgres, hay muchas otras cosas de las que preocuparseRecientemente se eligió ULID como PK en Postgres, y este artículo fue de gran ayuda: https://brandur.org/nanoglyphs/026-ids
Se prefiere ULID porque es compatible con el tipo UUID y, como tiene un timestamp incorporado, al ordenar por ID también se ordena por timestamp
Estaría bien incluir también
int64en la comparación para poder comparar la sobrecarga de UUID con la del enfoque tradicionalEl rendimiento de inserción es una mala forma de evaluar el rendimiento
En SQLite se prefiere UUID4 porque hay menos probabilidad de colisiones en la caché de páginas durante el bloqueo de transacciones
Se prefieren las claves primarias enteras autoincrementales
El benchmark de tiempo de inserción de UUIDv7 incluye el tiempo de generación del UUID
Es poco probable que PostgreSQL 17 incluya soporte para UUIDv7
Se empezó a usar
python-ulid, y ULID es superior a UUIDComo el enlace al estándar UUID v7 está desactualizado, conviene consultar RFC 9562: https://datatracker.ietf.org/doc/html/rfc9562