Intermedio6 min de lectura

Ordenar DynamoDB por un atributo cambiante (mutable)

Modelas una clave de ordenación alrededor de un atributo para poder consultar elementos en su orden — y entonces el atributo cambia. El estado de un ticket, el estado de un pedido, la prioridad de una tarea. Aquí está la trampa que te pone DynamoDB: no puedes actualizar un atributo clave in situ. Una clave primaria es inmutable durante toda la vida del elemento. Cambia un valor que forma parte de la clave y no estás editando un elemento — lo estás moviendo, algo que DynamoDB te obliga a hacer de forma explícita.

¿Se puede cambiar una clave de ordenación de DynamoDB?

No. La clave de ordenación forma parte de la clave primaria, y los atributos de clave en DynamoDB son inmutables — UpdateItem no puede editar el valor de una clave de partición ni de ordenación, y no existe ninguna operación de "mover elemento". Para cambiarlo, debes eliminar el elemento antiguo y crear uno nuevo, o bien mantener el valor volátil en la clave de ordenación de un GSI.

  • Los atributos clave son inmutables. No puedes hacer UpdateItem sobre el valor de una clave de partición o de ordenación — DynamoDB no tiene operación de "mover elemento".
  • Para cambiar el valor de una clave, eliminas el elemento antiguo y pones uno nuevo — idealmente en una transacción para que sea atómico.
  • Mejor: mantén el valor volátil fuera de la clave de la tabla base y ponlo en su lugar en una clave de ordenación de un GSI — las claves de un GSI pueden cambiar, porque actualizar el elemento base simplemente vuelve a propagar la entrada del índice.
  • Elige claves de ordenación que no cambien (marcas de tiempo, ids inmutables) siempre que el patrón de acceso lo permita.

El problema: un estado por el que quieres ordenar, que no para de cambiar

Digamos que gestionas un servicio de soporte y quieres listar los tickets de un equipo ordenados por estado, así que pones el estado en la clave de ordenación:

PK: TEAM#7   SK: STATUS#open#TICKET#8842

Ahora el ticket pasa a pending. Te gustaría simplemente hacer UpdateItem sobre la clave de ordenación a STATUS#pending#TICKET#8842 — pero DynamoDB rechaza cualquier escritura que cambie un atributo clave. La clave es la dirección del elemento; no puedes editar la dirección in situ. El estado que elegiste para ordenar es justo lo que no se queda quieto.

Opción 1: eliminar y recrear (atómicamente)

Si el valor debe vivir en la clave de la tabla base, cambiarlo significa eliminar el elemento antiguo y escribir el nuevo:

1. DeleteItem  PK=TEAM#7  SK=STATUS#open#TICKET#8842
2. PutItem     PK=TEAM#7  SK=STATUS#pending#TICKET#8842  (mismos atributos)

Hazlo dentro de un TransactWriteItems para que el delete y el put tengan éxito ambos o fallen ambos — de lo contrario un fallo entre ellos pierde el ticket o lo duplica. Esto funciona, pero cada cambio de estado son ahora dos escrituras más una transacción; bien para cambios ocasionales, costoso para los frecuentes.

Opción 2: mantén el valor mutable fuera de la clave base (preferida)

El diseño más limpio: haz que la clave de la tabla base sea algo inmutable (el id del ticket) y pon el valor volátil y ordenable en una clave de ordenación de un GSI.

Base:  PK: TICKET#8842   status: "open"   teamId: TEAM#7
GSI:   GSI1PK: TEAM#7    GSI1SK: STATUS#open#TICKET#8842

Ahora cambiar el estado es un simple UpdateItem sobre el atributo status del elemento base — lo cual DynamoDB permite, porque status no es una clave de la tabla base. DynamoDB entonces vuelve a propagar la entrada del GSI automáticamente a su nueva posición ordenada. Una escritura, sin transacción, sin baile de eliminar.

No, es una clave de ordenaciónde GSIEl estado cambia de open apending¿El valor está en una clave de latabla base?Eliminar + recrear en unatransacciónUpdateItem simple; el GSI vuelvea propagar

El compromiso: el GSI tiene consistencia eventual y cuesta almacenamiento/escrituras extra — pero para un valor que cambia a menudo, eso es mucho más barato que eliminar y recrear en cada cambio.

Diseñar las claves en DynoTable

Construye y previsualiza las condiciones de clave tanto para la lectura base como para la lectura del GSI en el constructor de expresiones de DynamoDB.

En DynoTable, luego eliges a través de qué índice se ejecuta una consulta y observas cómo el valor volátil se ordena en el GSI mientras el elemento base mantiene su clave inmutable — ambas lecturas una al lado de la otra sobre datos reales.

Consultando un GSI ordenado por estado mientras el elemento base mantiene una clave inmutable en DynoTable.
Consultando un GSI ordenado por estado mientras el elemento base mantiene una clave inmutable en DynoTable.

Trampas y próximos pasos

  • Nunca intentes hacer UpdateItem sobre un atributo clave — se rechaza; los valores de las claves son fijos durante toda la vida del elemento.
  • Si tienes que moverlo, haz delete+put en una transacción — nunca como dos escrituras sin protección.
  • Prefiere claves base inmutables + un GSI para cualquier atributo por el que ordenes y que mutes.
  • No olvides la consistencia eventual del GSI — la entrada reordenada aparece tras un breve retardo de propagación.
  • Relacionado: estrategias de claves de ordenación, 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.

Actualizado