Principiante7 min de lectura

Clave primaria compuesta en DynamoDB

Una clave primaria compuesta son dos atributos: una clave de partición y una clave de ordenación. La clave de partición decide dónde vive un item; la clave de ordenación ordena los items dentro de esa partición.

Si vienes de SQL, piénsalo menos como una columna id única y más como GROUP BY partition, ORDER BY sort integrado en la propia tabla.

¿Qué es una clave primaria compuesta en DynamoDB?

Una clave primaria compuesta en DynamoDB combina dos atributos: una clave de partición y una clave de ordenación. La clave de partición decide en qué partición física vive un item; la clave de ordenación ordena los items dentro de esa partición. Juntas forman la identidad única del item y permiten que un solo Query devuelva un rango ordenado en lugar de un único item.

  • Dos partes, dos trabajos. La clave de partición enruta el item a una partición física; la clave de ordenación ordena cada item que comparte esa clave de partición.
  • La unicidad es el par. Dos items pueden compartir un valor de clave de partición siempre que sus claves de ordenación difieran — así es como una partición contiene muchas filas.
  • La clave de ordenación lo es todo. Es lo que permite que un Query devuelva un rango (>=, between, begins_with) en lugar de un solo item, sin Scan.
  • Las claves deben ser escalares. Las claves de partición y de ordenación solo pueden ser cadena, número o binario — sin mapas, sin listas (Documentación de AWS).

Clave simple vs clave compuesta

Una clave primaria simple es solo una clave de partición. Identifica un item de forma única, y lo lees de vuelta con GetItem. Eso es todo — sin lecturas de rango, sin "dame los N más recientes".

Una clave compuesta añade la clave de ordenación, y esa única adición es lo que hace que DynamoDB se sienta como una base de datos en lugar de un mapa hash.

Clave simpleClave compuesta
AtributosSolo clave de particiónClave de partición + clave de ordenación
UnicidadValor de la clave de particiónEl par de valores
Múltiples items por particiónNo
Query de un rangoNo (solo GetItem)Sí (begins_with, between, >)
Encaje naturalBúsqueda por idSeries temporales, uno a muchos, historial

Modela una tabla de lecturas de sensores

Supón que recoges muestras de temperatura de una flota de sensores de campo. El patrón de acceso es "obtén las lecturas de un dispositivo, las más nuevas primero, dentro de una ventana de tiempo". Eso es una clave compuesta de manual.

Usa el id del dispositivo como clave de partición y la marca de tiempo de la lectura como clave de ordenación:

deviceIdreadingTstempChumidity
DEV#a1b22026-06-23T08:00:00Z21.448
DEV#a1b22026-06-23T08:05:00Z21.747
DEV#a1b22026-06-23T08:10:00Z22.146
DEV#c9d82026-06-23T08:00:00Z19.855

Las tres lecturas de DEV#a1b2 aterrizan en la misma partición, almacenadas físicamente juntas y ordenadas por readingTs.

AWS llama a la clave de partición el atributo hash y a la clave de ordenación el atributo range — la clave de ordenación es un rango dentro del que puedes escanear (Documentación de AWS).

Aquí está cómo los items colapsan en una sola item collection bajo cada clave de partición:

Partición: DEV#a1b2readingTs 08:00readingTs 08:05readingTs 08:10Query deviceId = DEV#a1b2

Un Query contra la clave de partición lee cada lectura de ese dispositivo, ya en orden de marca de tiempo — sin ordenar en el cliente, sin un segundo viaje de ida y vuelta.

Consulta el rango, no lo escanees

Como readingTs es una cadena ISO-8601, se ordena lexicográficamente de la misma forma que se ordena cronológicamente. Así que una lectura de ventana de tiempo es un rango de condición de clave, no un filtro:

Query
deviceId  = "DEV#a1b2"
readingTs BETWEEN "2026-06-23T08:00:00Z" AND "2026-06-23T08:10:00Z"

Eso es un KeyConditionExpression — estrecha la lectura antes de que DynamoDB devuelva los datos, así que pagas solo por los items de la ventana. Un FilterExpression se ejecuta después de la lectura y te factura por todo lo que escaneó; ese es el error del Scan en miniatura.

La expresión en sí, con placeholders y valores tipados, es engorrosa de escribir a mano. Constrúyela visualmente con el DynamoDB Expression Builder y copia el KeyConditionExpression exacto en tu llamada al SDK.

Diseña la clave de ordenación a propósito

La clave de ordenación no es metadato gratis — es la única palanca para lecturas de rango, así que moldéala a tus consultas.

  • Usa una marca de tiempo ordenable. Las cadenas ISO-8601 o los números epoch rellenados con ceros se ordenan correctamente; las fechas localizadas en crudo no.
  • Ponle un prefijo para overloading de uno a muchos. Una clave de ordenación como READING#2026-06-23T08:00:00Z te permite mezclar tipos de entidad bajo una partición y cortarlos con begins_with. Esa es la costura hacia el single-table design.
  • Pon la dimensión de alta cardinalidad en la clave de partición. El id del sensor tiene miles de valores, así que reparte las escrituras de forma equitativa. Una clave de partición de baja cardinalidad (digamos, region) crea una partición caliente.

Cuándo una clave compuesta te muerde

Es un compromiso, no una comodidad. La trampa: eliges una clave de partición, despliegas, y luego descubres un patrón de acceso que necesita una agrupación diferente — "todas las lecturas por encima de 30°C en toda la flota".

La tabla base no puede responder eso; la clave de partición es fija. Tus opciones son un global secondary index con una clave diferente, o reestructurar.

Enumera tus lecturas antes de comprometer el esquema de claves. Cambiar una clave primaria significa una migración de tabla, no un ALTER TABLE.

Próximos pasos

Las claves compuestas son la base sobre la que se asientan las item collections, las relaciones de uno a muchos y la mayoría de los diseños útiles de índices — lee single-table design y GSI vs LSI a continuación para ver a dónde llevan.

Esboza tu KeyConditionExpression en el DynamoDB Expression Builder, luego prueba DynoTable para navegar tus particiones reales y ver el orden de ordenación alinearse contra tus propias tablas.

Actualizado