Ordenar DynamoDB por un atributo que cambia
Modelas una clave de ordenación alrededor de un atributo para poder consultar items en ese orden — y luego el atributo cambia. El status de un ticket, el estado de un pedido, la prioridad de una tarea. La regla de DynamoDB: no puedes actualizar un atributo de clave in place. Una clave primaria es inmutable durante la vida del item. Cambiar un valor que forma parte de la clave no es editar un item — es moverlo, y DynamoDB te obliga a hacerlo de forma explícita.
¿Puedes cambiar la clave de ordenación de DynamoDB?
No. Una clave de ordenación forma parte de la clave primaria, y los atributos de clave de DynamoDB son inmutables — UpdateItem no puede editar el valor de una clave de partición o de ordenación, y no hay operación de "mover item". Para cambiarla, borra el item viejo y pon uno nuevo, o deja el valor volátil en la clave de ordenación de un GSI.
- Los atributos de clave son inmutables. No puedes hacer
UpdateItemdel valor de una clave de partición o de ordenación — DynamoDB no tiene operación de "mover item". - Para cambiar un valor de clave borras el item viejo y pones uno nuevo — idealmente en una transacción para que sea atómico.
- Mejor: deja el valor volátil fuera de la clave de la tabla base y ponlo en la clave de ordenación de un GSI — las claves de GSI sí pueden cambiar, porque actualizar el item base solo repropaga la entrada del índice.
- Elige claves de ordenación que no cambien (timestamps, ids inmutables) siempre que el patrón de acceso lo permita.
El problema: un status por el que quieres ordenar, y que no para de cambiar
Digamos que llevas un support desk y quieres listar los tickets de un equipo ordenados por status, así que pones el status en la clave de ordenación:
PK: TEAM#7 SK: STATUS#open#TICKET#8842Ahora el ticket pasa a pending. Te gustaría solo hacer UpdateItem de la clave de ordenación a
STATUS#pending#TICKET#8842 — pero DynamoDB rechaza cualquier escritura que cambie un atributo
de clave. La clave es la dirección del item; no puedes editar la dirección in place. El
status que elegiste para ordenar es exactamente lo que no se queda quieto.
Opción 1: borrar y recrear (de forma atómica)
Si el valor debe vivir en la clave de la tabla base, cambiarlo significa quitar el item viejo y escribir el nuevo:
1. DeleteItem PK=TEAM#7 SK=STATUS#open#TICKET#8842
2. PutItem PK=TEAM#7 SK=STATUS#pending#TICKET#8842 (same attributes)Hazlo dentro de un TransactWriteItems para que el delete y
el put tengan éxito o fallen juntos — si no, un crash entre medias pierde el
ticket o lo duplica. Funciona, pero cada cambio de status son ahora dos escrituras más una
transacción; bien para cambios ocasionales, caro para los calientes.
Opción 2: deja el valor mutable fuera de la clave base (preferido)
Haz que la clave de la tabla base sea algo inmutable (el id del ticket) y pon el valor volátil y ordenable en la clave de ordenación de un GSI.
Base: PK: TICKET#8842 status: "open" teamId: TEAM#7
GSI: GSI1PK: TEAM#7 GSI1SK: STATUS#open#TICKET#8842Ahora cambiar el status es un UpdateItem plano del atributo status del item base —
que DynamoDB permite, porque status no es una clave de la tabla base. DynamoDB entonces
repropaga la entrada del GSI automáticamente a su nueva posición ordenada. Una llamada a la API,
con atomicidad resuelta por ti — sin transacción, sin baile de deletes (bajo el capó DynamoDB
sigue borrando la entrada vieja del índice y escribiendo la nueva, así que un cambio indexado cuesta ~3
unidades de escritura frente a las ~4 de un delete-and-put transaccional).
El GSI es de consistencia eventual y cuesta almacenamiento/escrituras extra — pero para un valor que cambia a menudo, eso es algo más barato (~3 vs 4 unidades de escritura) y mucho más simple que delete-and-recreate en cada cambio.
Diseñar las claves en DynoTable
Construye y previsualiza las condiciones de clave tanto para la lectura base como para la del GSI en el generador de expresiones de DynamoDB.
En DynoTable, luego eliges por qué índice corre una query y ves el valor volátil ordenarse en el GSI mientras el item base mantiene su clave inmutable — ambas lecturas lado a lado sobre datos reales.

Escollos + próximos pasos
- Nunca intentes
UpdateItemde un atributo de clave — se rechaza; los valores de clave están fijos durante la vida del item. - Si debes moverlo, haz delete+put en una transacción — nunca como dos escrituras sin guarda.
- Prefiere claves base inmutables + un GSI para cualquier atributo por el que ordenas y mutas.
- No olvides la consistencia eventual del GSI — la entrada reordenada aparece tras un breve retraso de propagación.
- Relacionado: estrategias de sort-key, GSI vs LSI, transacciones.
¿Quieres ver cómo un atributo mutable se ordena en un GSI frente a la tabla base? Descarga DynoTable y explora tus índices directamente.
Coste de escritura: delete-and-put vs update de GSI
Comparación aproximada de WCU para un ticket de 1 KB en us-east-1 on-demand (la facturación
real sigue las reglas de redondeo de AWS):
| Patrón | Llamadas API | Impacto típico de WCU |
|---|---|---|
| Delete + put transaccional en clave base | TransactWriteItems (2 ops) | ~2× tamaño del item por op en pricing de transacción |
Update del atributo status; el GSI se repropaga | Un UpdateItem | Escritura base + escritura GSI (~2 WCU por item 1 KB + attrs proyectados) |
El camino del GSI evita orquestación a nivel de aplicación y elimina la ventana donde un crash entre delete y put pierde la fila. Cambias consistencia eventual en la lectura del índice por escrituras más simples.
Modela el tamaño del item y la tasa de updates en la calculadora de pricing cuando los cambios de status disparan muchas veces por minuto.
GSI sparse para listas ordenadas por status
Si solo los tickets open necesitan una cola ordenada por status, usa un
índice sparse: escribe GSI1PK = TEAM#7 y
GSI1SK = STATUS#open#... solo mientras status = open. Cuando el ticket se cierra,
quita u omite los atributos de clave del GSI en el update — el item sale del
índice sin un delete-and-put en la clave de ordenación base.
Eso mantiene el índice pequeño y evita indexar tickets cerrados que nunca listas.
Claves base inmutables a preferir
| Campo volátil | SK de tabla base | Mejor SK base | El campo volátil vive en |
|---|---|---|---|
| Status del pedido | STATUS#shipped#ORD#99 | ORD#99 | Sort del GSI o atributo |
| Prioridad de tarea | P#1#TASK#12 | TASK#12 | Sort del GSI |
| Nombre visible de user | NAME#alice#USER#5 | USER#5 | Atributo no-clave |
Timestamps e ids inmutables (CREATED#2026-06-27T10:00:00Z, TICKET#8842)
hacen claves de ordenación base estables cuando necesitas orden cronológico en la propia
tabla base.
Diseña el GSI antes de codear
Mapea patrones de acceso en la
herramienta de single-table design — introduce "listar
tickets open por equipo, orden de prioridad" e inspecciona las plantillas sugeridas de GSI1PK /
GSI1SK. Luego construye la condición de clave en el
expression builder y emite una query paginada
con el query builder para tests de integración.
Read-your-writes tras un cambio de status
Tras un UpdateItem, una lectura de consistencia fuerte en la tabla base muestra el
nuevo status al instante. Una query en el GSI puede ir un poco por detrás. Los flujos de UI que
redirigen a una cola ordenada por GSI deberían tolerar filas stale o re-fetch desde la
tabla base por id cuando la precisión importa.


