Cuándo NO usar single-table design en DynamoDB
El single-table design es el consejo por defecto para DynamoDB, y se lo gana: un Query
devuelve un padre y sus hijos, sin joins, sin N+1.
Pero es un intercambio — compras velocidad de lectura con un esquema rígido y opaco. Algunas cargas de trabajo no pueden permitirse ese precio, y forzar una sola tabla sobre ellas es su propio error de diseño.
¿Cuándo no deberías usar single-table design en DynamoDB?
Evita el single-table design cuando tu carga de trabajo sea analítica OLAP intensiva, CRUD sencillo sobre un puñado de entidades no relacionadas, o entidades que escalan y fallan de forma independiente. En esos casos, varias tablas son más legibles, cuestan lo mismo y mantienen la flexibilidad. El single-table design solo gana cuando los patrones de acceso son conocidos, relacionados y de alto volumen.
- ¿Analítica pesada? No hagas single-table. Las claves sobrecargadas son hostiles para OLAP — exporta a un almacén columnar y consulta allí.
- ¿CRUD sencillo con un puñado de patrones de acceso? Una tabla por entidad está bien, es legible y no te cuesta nada en rendimiento.
- ¿Entidades que escalan o fallan de forma independiente? Tablas separadas te dejan ajustarlas, facturarlas y aislar su radio de impacto por separado.
- El single-table sigue ganando cuando tus patrones son conocidos, relacionados y de alto volumen — ese es el caso para el que se construyó.
Conoce lo que realmente cuesta el single-table
El single-table design no es gratis; solo mueve el coste fuera de la ruta de lectura y hacia todo lo demás. Pagas en legibilidad y flexibilidad.
Una tabla que contiene cinco tipos de entidad detrás de PK/SK es difícil de leer,
difícil de incorporar a alguien y difícil de cambiar. Un nuevo patrón de acceso puede
significar un backfill sobre cada tipo de item de la partición.
Así que la pregunta no es "¿es bueno el single-table?". Es "¿justifican mis patrones de acceso la rigidez?". Cuando no lo hacen, recurre a varias tablas.
No hagas single-table en una carga de trabajo analítica
DynamoDB está construido para OLTP — lecturas pequeñas, conocidas, puntuales y de rango.
La analítica es OLAP: GROUP BY, grandes agregados, troceado ad-hoc de todo el conjunto
de datos. Los dos tiran en direcciones opuestas.
El single-table design empeora el OLAP, no lo mejora. Las claves sobrecargadas y los tipos de entidad mezclados significan que un trabajo de analítica primero debe desenredar qué item es cuál antes de poder sumar nada — lo opuesto a un scan columnar limpio.
Si vienes de SQL, el reflejo es escribir el agregado contra la tabla en vivo. En DynamoDB
eso es un Scan completo — pagas por y lees cada item, que es el
error del Scan a todo volumen.
La solución no es una clave más astuta. Es un almacén diferente. La propia guía de AWS es exportar DynamoDB a S3 y ejecutar la analítica con un motor de consultas como Athena.
Mantén OLTP y OLAP en motores separados (AWS DynamoDB Developer Guide,
S3DataExport.html).
No hagas single-table en CRUD simple
Si tu app lee y escribe unas pocas entidades no relacionadas por su propio id, y tienes quizá tres patrones de acceso, el single-table no te compra nada.
Toma una tabla Tenants y una tabla ApiKeys para una pequeña herramienta B2B:
| TenantId | Name | PlanTier |
|---|---|---|
| TNT-8842 | Northwind | pro |
| KeyId | TenantId | Scope |
|---|---|---|
| KEY-01H9... | TNT-8842 | read-write |
Cada consulta es un GetItem por id, o un Query sobre un GSI con clave por TenantId.
No hay un fetch de padre-e-hijos que optimizar, así que no hay nada que una partición
sobrecargada pueda ganar. Dos tablas claras se leen mejor que una turbia.
La trampa es hacer single-table por imitación porque es "mejor práctica". La mejor práctica es patrones-de-acceso-primero. Si los patrones son triviales, la forma simple es la forma correcta.
Divide las tablas que escalan o fallan de forma independiente
Una sola tabla comparte una superficie de rendimiento, un backup, un radio de impacto. Cuando dos entidades tienen tasas de escritura o necesidades de durabilidad radicalmente distintas, ese destino compartido se vuelve una responsabilidad.
Imagina un sistema de seguimiento de flotas. Los vehículos cambian rara vez; su telemetría entra a chorro cada segundo:
| VehicleId | Make | Model | Region |
|---|---|---|---|
| VEH-204 | Volvo | FH16 | eu-west |
| DeviceTs | VehicleId | SpeedKph | Fuel |
|---|---|---|---|
| 2026-06-23T10:00:01Z | VEH-204 | 88 | 0.61 |
Dos tablas te dejan aprovisionar la telemetría para una manguera de incendios, mantener los vehículos diminutos y baratos, poner un TTL solo a la telemetría, y evitar que una tormenta de escrituras de telemetría throttlee las lecturas del catálogo de vehículos. Una sola tabla acopla todo eso.
Según el paper Amazon Dynamo de 2007, la partición y la disponibilidad son preocupaciones de primera clase — las tablas independientes te dan control independiente sobre ambas.
Traza la decisión antes de comprometerte
Pasa la carga de trabajo por una sola puerta: ¿están relacionadas las entidades, y son los patrones conocidos y de alto volumen? Si no, varias tablas.
Aquí está la decisión como un flujo — empieza arriba y sigue la primera rama que coincida:
Solo la hoja inferior derecha se gana el single-table; cualquier otra ruta queda mejor servida por más de una tabla.
Single vs varias, cara a cara
| Factor | Single-table | Varias tablas |
|---|---|---|
| Lecturas relacionadas | Un Query, sin joins | Join del lado del cliente o viajes extra |
| Legibilidad | Claves sobrecargadas opacas | Una entidad por tabla, autodocumentada |
| Nuevo patrón de acceso | A menudo un backfill | Añadir una tabla o GSI de forma aislada |
| Analítica / OLAP | Hostil — desenredar antes de agregar | Sigue exportando, pero más limpio por entidad |
| Escalado independiente | Rendimiento + radio de impacto compartidos | Ajustar, facturar, TTL y backup por separado |
| Mejor cuando | Patrones conocidos, relacionados, de alto volumen | No relacionados, en evolución, o analíticos |
Trampas + próximos pasos
El error simétrico es sobrecorregir — dividir entidades genuinamente relacionadas y de alto volumen en una tabla por entidad y reconstruir joins al estilo SQL en tu app. Esa es la trampa N+1 que el single-table mata.
Elige la forma que pidan los patrones de acceso, no el dogma.
Cuando sí modeles relaciones, apóyate en el tipo de índice correcto — ver GSI vs LSI antes de añadir uno.
Cuando sí escribas una consulta contra un esquema multi-tabla, esboza primero el
KeyConditionExpression en el
DynamoDB Expression Builder.
Así detectas una forma de Scan completo antes de que llegue a producción.
Luego prueba DynoTable para navegar ambas formas contra tus propias tablas y ver cuál quieren realmente tus patrones de acceso.