Estrategias de sort key en DynamoDB: 3 patrones y cuándo usar cada uno
Una clave primaria de DynamoDB es uno o dos atributos: una sola, o una clave de partición más una clave de ordenación. La clave de partición decide qué partición física contiene un elemento.
La clave de ordenación decide el orden de los elementos dentro de esa partición — y ese
orden es lo que hace potente a Query.
Elige la clave de ordenación equivocada y aún podrás escribir datos, pero pierdes las lecturas de rango, la ordenación y varios patrones de acceso desde una sola colección.
Viniendo de SQL, recurrirías a un ORDER BY o a un índice secundario a
posteriori. En DynamoDB grabas el orden en la clave desde el principio, o no lo obtienes.
¿Cómo funcionan las claves de ordenación de DynamoDB?
Una clave de ordenación de DynamoDB ordena los elementos dentro de una partición, de modo que Query puede hacer lecturas de rango — >=, between, begins_with — en lugar de recuperar un elemento a la vez. Las claves de ordenación de tipo cadena se ordenan por bytes UTF-8 (las de tipo Number se ordenan numéricamente), así que diseña una clave de cadena (una marca de tiempo ISO-8601, un número rellenado con ceros) para que el orden de bytes coincida con el orden en que quieres leer.
- La clave de ordenación es tu índice dentro de la partición. Ordena la en
disco, de modo que
Querypuede hacer lecturas de rango (>=,between,begins_with) en lugar de un únicoGetItem. - Las claves de ordenación de tipo cadena se ordenan por bytes UTF-8 (las de tipo Number se ordenan numéricamente). Diseña una
clave de cadena para que el orden de bytes coincida con el orden en que quieres leer — una marca de tiempo
ISO-8601, un número rellenado con ceros, nunca un UUID crudo ni
6/23/2026. - Una clave de ordenación bien formada sirve a muchos patrones de acceso. Una
(
EVT#<timestamp>) es un prefijo y un rango a la vez — sin necesidad de un GSI. - La dirección es gratis.
ScanIndexForward = falselee del más reciente al más antiguo al mismo coste; no almacenes marcas de tiempo invertidas para fingirlo.
Por qué la clave de ordenación es la palanca
Sin una clave de ordenación, cada elemento de una partición es direccionable solo por su
clave primaria completa — un GetItem en el mejor caso. Añade una clave de ordenación y DynamoDB almacena los elementos
ordenados por ella dentro de la partición, lo que desbloquea Query.
Eso significa condiciones de rango (>=, between), coincidencia de prefijos (begins_with),
y un flag ScanIndexForward para leer en orden ascendente o descendente.
Según la Guía para desarrolladores de DynamoDB de AWS, todos los elementos que comparten una clave de partición forman una colección de elementos, ordenada en disco por la clave de ordenación.
Así que la clave de ordenación no es solo un segundo identificador. Es el índice contra el que consultas dentro de una partición.
Ese orden es el orden de bytes de la clave de ordenación codificada: las cadenas se comparan por bytes UTF-8, los números se comparan numéricamente. Este único hecho impulsa casi todas las estrategias de abajo.
Si quieres que las consultas de rango signifiquen algo, el orden de bytes tiene que coincidir con el orden en que quieres leer.
Estrategia 1: haz la clave de ordenación ordenable
El error más común es una clave de ordenación que no está ordenada de forma significativa. Un UUID aleatorio te da unicidad pero ninguna consulta de rango útil — "dame los últimos 20" se vuelve imposible porque el orden de bytes es arbitrario.
En su lugar, codifica el valor por el que ordenas y filtras en la clave de ordenación, en una representación cuyo orden de bytes coincida con su orden lógico. Para marcas de tiempo eso significa un formato ordenable lexicográficamente: una cadena ISO-8601 o un epoch rellenado con ceros.
ISO-8601 se diseñó para que la comparación de cadenas equivalga a la comparación cronológica —
exactamente lo que necesita una consulta de rango. Evita formatos como 6/23/2026; se ordenan mal
en cuanto cambia el mes.
Si ordenas por números (un contador de versión, una puntuación), usa el
tipo Number nativo de DynamoDB en lugar de una cadena, para que 42 se ordene después de 9 y no antes.
Si un número debe vivir dentro de una clave de ordenación compuesta de tipo cadena, rellénalo con ceros a un ancho fijo.
Estrategia 2: claves de ordenación compuestas para jerarquía
Una clave de ordenación puede codificar una jerarquía concatenando segmentos con un delimitador,
lo más común #. Una condición begins_with selecciona entonces un subárbol entero:
| SK |
|---|
| EVENT#2026-06#01#login |
| EVENT#2026-06#03#export |
| EVENT#2026-07#02#login |
begins_with(SK, "EVENT#2026-06#") devuelve solo los eventos de junio; el más amplio
begins_with(SK, "EVENT#") los devuelve todos.
El orden de los segmentos es una decisión de diseño. De grueso a fino (año → mes → día) mantiene los elementos relacionados contiguos, de modo que una lectura de rango sigue siendo una consulta barata en lugar de una dispersión por la partición.
Estrategia 3: controla la dirección con ScanIndexForward
DynamoDB almacena los elementos en orden ascendente de clave de ordenación y los lee así por
defecto. Para leer del más reciente al más antiguo — el orden natural para un feed de actividad — pon
ScanIndexForward = false en la Query.
Este es un flag en tiempo de lectura, no una decisión de esquema: la misma colección sirve para ambas direcciones al mismo coste. No inviertas tus marcas de tiempo (almacenando un "epoch inverso") solo para obtener lecturas descendentes.
Una colección de elementos, almacenada una sola vez en orden ascendente, leída en cualquier sentido:
Mismos elementos, misma partición, mismo coste — solo cambia la dirección de lectura.
Ejemplo resuelto: un registro de auditoría acotado por actor
Supón que registras eventos con marca de tiempo producidos por actores — usuarios, servicios, claves de API — en un producto SaaS, y tienes dos lecturas:
- El flujo de actividad de un actor, con el evento más reciente primero.
- Los eventos de un actor dentro de una ventana temporal (p. ej. "todo entre los dos despliegues"), para una investigación.
Ambas lecturas están acotadas a un único actor, así que el actor es la clave de partición y la hora del evento es la clave de ordenación. Usa nombres de clave genéricos para que la misma tabla pueda contener otras entidades más adelante:
| PK | SK | attributes |
|---|---|---|
| ACTOR#u_8814 | EVT#2026-06-23T09:12:04Z | action=login, ip, ua |
| ACTOR#u_8814 | EVT#2026-06-23T14:05:11Z | action=export, target |
| ACTOR#u_8814 | EVT#2026-06-24T08:40:55Z | action=login, ip, ua |
| ACTOR#svc_billing | EVT#2026-06-23T00:00:00Z | action=invoice.run |
El prefijo EVT# más una marca de tiempo ISO-8601 dan una clave de ordenación ordenable. La lectura 1 es
Query PK = "ACTOR#u_8814" con ScanIndexForward = false para el más reciente primero. La lectura
2 acota la misma partición con una condición between sobre la clave de ordenación:
Query
PK = "ACTOR#u_8814"
AND SK BETWEEN "EVT#2026-06-23T00:00:00Z"
AND "EVT#2026-06-23T23:59:59Z"
Una colección, dos patrones de acceso, sin GSI — porque la clave de ordenación es a la vez un prefijo
(EVT#) y un rango (la marca de tiempo). La lectura descendente y la lectura por ventana son
los mismos elementos en el mismo orden; solo difieren los parámetros.
Construyendo esa condición de clave a mano, es fácil equivocarse con los límites del between o
con el escapado de palabras reservadas en los nombres de atributo.
El Generador de expresiones de DynamoDB
genera la KeyConditionExpression, los ExpressionAttributeNames y los
ExpressionAttributeValues para una condición de clave de ordenación begins_with o between.
Cópialo directamente en tu llamada del SDK en lugar de depurar el escapado en tiempo de ejecución.
Hazlo en DynoTable
Diseñar una clave de ordenación es iterativo: escribe unos pocos elementos representativos, ejecuta la consulta de rango y comprueba que las filas vuelven en el orden que esperas. Hacer eso contra una tabla en vivo en una GUI supera al ir y venir a través del código.

Cambia la dirección de ordenación, ajusta los límites del between y observa cómo cambia la
colección devuelta sin escribir una línea de código — la forma más rápida de confirmar un
diseño de clave de ordenación antes de comprometerte con él.
Escollos y próximos pasos
- Las claves de ordenación deben ser únicas dentro de una partición. Si dos eventos pueden compartir una marca de tiempo, añade un desambiguador (un número de secuencia o un id corto) a la clave de ordenación para que la compuesta siga siendo única.
- Una partición caliente no se soluciona ordenando. Si un actor produce muchos más eventos que el resto, la clave de ordenación no te salvará — necesitas un diseño de clave de partición que reparta la carga. Mira diseño de tabla única.
- Un segundo orden de ordenación necesita un segundo índice. La clave de ordenación de la tabla base da un orden. Para ordenar los mismos elementos de forma diferente (por tipo de evento, digamos), añade un GSI con una clave de ordenación distinta — sopesando los compromisos del índice secundario local frente al global.
- No recurras a
Scanpara "ordenar después". Ordenar en el cliente tras unScanlee toda la tabla y tira el orden a la basura; ese es el peligro del Scan. Empuja el orden hacia la clave de ordenación en su lugar.
Una vez que la condición de clave sea correcta, prueba DynoTable para modelar la colección, ejecutar las consultas ascendente y descendente en paralelo y verificar tu estrategia de clave de ordenación contra datos reales antes de que se despliegue.


