Mis notas sobre el diseño del esquema Postgres de GitLab (2022)
Las decisiones de esquema PostgreSQL de GitLab provocan una crítica amplia sobre cómo las aplicaciones modernas modelan datos a escala. Los comentaristas examinan los compromisos entre claves primarias de 32 y 64 bits, UUIDs frente a IDs secuenciales, y estrategias de migración de esquema en línea, destacando cómo la localidad de índice, las claves foráneas y las abstracciones de ORM pueden hacer o deshacer el rendimiento en tablas con miles de millones de filas. El hilo también cuestiona “mejores prácticas” comunes como ocultar las claves primarias a los usuarios, argumentando que a menudo reflejan preocupaciones empresariales y competitivas más que seguridad, y enfatizando que un diseño cuidadoso, centrado en la base de datos, sigue siendo crucial pese a los avances en herramientas.
Tamaño de la clave primaria, migraciones y herramientas
- Muchos comentarios debaten entre PKs int y bigint. Algunos sostienen que alcanzar los límites de 32 bits es un riesgo real para servicios grandes y “demasiado cerca para estar tranquilos”, mientras que otros señalan que los datos reales (por ejemplo, repositorios/issues de GitHub) siguen por debajo de 2^31.
- Se describe que migrar de int→bigint es factible pero no trivial a escala: reescrituras de tablas, reconstrucción de índices, claves foráneas y la creación de índices en un solo hilo pueden llevar horas en tablas de varios TB.
- Se mencionan enfoques de cero/bajo tiempo de inactividad: replicación lógica con switchover, herramientas de cambio de esquema en línea (pg-osc, gh-ost), desacoplar las migraciones de esquema de los despliegues de la app, y sistemas de migración operados por DBAs.
- Algunos señalan dolor adicional: deserialización de bigint en JavaScript, consumidores posteriores que asumen ints de 32 bits.
UUIDs frente a enteros secuenciales
- Se critica UUIDv4 como PK principalmente por rendimiento, no por tamaño. 8 bytes extra por entrada de FK/índice se acumulan en muchas tablas y hacen más difícil que los índices quepan en RAM.
- Los UUID aleatorios destruyen la localidad del índice: las inserciones btree quedan dispersas, causan bloat de páginas y provocan fuertes caídas de rendimiento cuando los índices superan la memoria, no solo una penalización estable de ~25%.
- Se discuten IDs ordenados por tiempo (UUIDv6/v7, estilo Snowflake, secuencias cifradas o permutadas) como mejores compromisos, pero con trade-offs (filtración de tiempo, rotación de claves, complejidad).
Diseño de esquema, ORMs y migraciones
- Varios argumentan que el diseño de esquemas es “de la edad de piedra” y que las herramientas de migración (EF, Rails, Django, Prisma, etc.) o bien generan migraciones peligrosas (bloqueos, reescrituras) o bien ocultan lo que realmente se ejecuta.
- Hay una fuerte corriente a favor de pensar primero en el esquema y usar SQL simple (a menudo con procedimientos almacenados) en lugar de ORMs pesados, que se consideran propensos a filtraciones, complejos y difíciles de operar a escala.
- Otros defienden los ORMs como útiles para consultas dinámicas y grafos de objetos complejos, si se usan con comprensión.
Arquitectura y rendimiento de GitLab frente a GitHub
- Algunos perciben que las páginas de GitLab son notablemente más lentas que las de GitHub. Las explicaciones ofrecidas incluyen la cultura y la priorización del rendimiento, pero los detalles son anecdóticos e incompletos.
- Hay desacuerdo/incertidumbre sobre si GitLab.com es una sola base de datos multi-tenant o una base de datos por cliente; un comentario afirma que esencialmente es una instancia multi-tenant de su producto autohospedado.
Exponer claves primarias y “external IDs”
- Un sector ve ocultar PKs secuenciales como mayormente “teatro de seguridad”; si la autorización está rota, los IDs adivinados no deberían importar.
- Otros enfatizan la defensa en profundidad y la inteligencia competitiva: los IDs secuenciales revelan conteos/crecimiento (pedidos, usuarios, issues) y facilitan la enumeración masiva y la explotación.
- Los ejemplos incluyen volúmenes de pedidos en e-commerce, enumeración de usuarios y scraping; los contraargumentos afirman que los atacantes motivados a menudo pueden inferir datos similares de todos modos.
- El
idinterno al estilo GitLab más uniidpor proyecto se ve como algo más amigable para el usuario y desacopla las URLs de los cambios en el PK interno, a costa de joins e índices adicionales.
Detalles específicos de Postgres: text frente a varchar, FKs
- La discusión aclara que en Postgres,
textfrente avarchar(n)no tiene diferencia de rendimiento en tiempo de ejecución; el problema real es el coste de migración al cambiar longitudes envarchar(n)frente a ajustar unCHECKsobretext. - Un comentarista rebate la idea de que las claves foráneas sean “caras”, argumentando que la integridad debe imponerse en algún lugar y que las FKs a nivel de base de datos suelen ganar si se usan correctamente.