Intermedio4 min de lectura

Diseño de tabla única en DynamoDB

Viniendo de SQL, el instinto es una tabla por entidad: customers, orders, order_items. En DynamoDB ese instinto suele estar equivocado. Una única tabla que almacena todas las entidades, distinguidas por prefijos de clave sobrecargados, te permite obtener un padre y sus hijos en un Query —sin joins, sin N+1.

Empieza por los patrones de acceso, no por las entidades

El diseño de tabla única es lo primero el patrón de acceso. Antes de elegir una única clave, escribe cada lectura que hace tu aplicación —«obtener el perfil de un cliente», «listar los pedidos de un cliente de más nuevo a más antiguo», «encontrar todos los pedidos abiertos»— porque las claves existen solo para servir esa lista. La normalización relacional optimiza el almacenamiento; el modelado de DynamoDB optimiza las consultas que ya sabes que vas a ejecutar. Enuméralas y luego diseña las claves para que cada una sea un único Query.

La idea

Elige nombres de clave genéricos (PK, SK) y codifica el tipo de entidad en el valor:

PKSKattributes
CUSTOMER#42PROFILEname, email, plan
CUSTOMER#42ORDER#2026-001total, status
CUSTOMER#42ORDER#2026-002total, status

Ahora un Query PK = "CUSTOMER#42" devuelve el perfil y todos los pedidos en una sola lectura facturada. SK begins_with "ORDER#" lo acota solo a los pedidos.

Visualmente, los Items sobrecargados se apilan bajo una única clave de partición como una sola colección de Items:

Partition: CUSTOMER#42SK: PROFILESK: ORDER#2026-001SK: ORDER#2026-002One Query

Una sola lectura de la partición te devuelve el cliente y todos los pedidos juntos.

GSI sobrecargados

El mismo truco funciona en los índices. Pon un GSI1PK/GSI1SK genérico en los Items, y un único GSI sirve a múltiples patrones de acceso según lo que cada Item escriba en esos atributos:

PKSKGSI1PKGSI1SK
ORDER#001METADATASTATUS#OPEN2026-01-04
ORDER#002METADATASTATUS#OPEN2026-01-05

Ahora Query GSI1 WHERE GSI1PK = "STATUS#OPEN" lista los pedidos abiertos por fecha —un patrón que la tabla base no puede responder. Una entidad diferente puede reutilizar GSI1 con su propio significado (p. ej. CATEGORY#books). Un índice, muchas consultas.

Muchos a muchos: la lista de adyacencia

Para las relaciones (un usuario en muchos equipos, un equipo con muchos usuarios), escribe la arista dos veces con los ids intercambiados: PK=USER#1, SK=TEAM#9 y PK=TEAM#9, SK=USER#1. Consultar cualquiera de los dos lados lista el otro —el sustituto de DynamoDB para una tabla de join.

Cuándo no usar tabla única

No es gratis. Una tabla sobrecargada es más difícil de razonar, más difícil de evolucionar y hostil a la analítica. Si tus patrones de acceso son genuinamente desconocidos o cambian constantemente, o si los datos son mayormente analíticos, tablas separadas (u otro almacén) pueden ser la decisión más sensata. La tabla única gana cuando los patrones son conocidos y de alto volumen.

El coste de la forma equivocada

Modelar como tablas separadas obliga a un Scan o a un join en el lado del cliente para reensamblar un cliente, y ese es el footgun del Scan. Modela primero los patrones de acceso y luego diseña las claves para que cada uno sea un Query.

Estima lo que cuestan estos Items por lectura con la calculadora de tamaño de Items y capacidad, y prueba DynoTable para explorar un schema de tabla única y ver las colecciones sobrecargadas en paralelo.

Actualizado