Intermedio6 min di lettura

Ordinare DynamoDB su un attributo che cambia (mutabile)

Modelli una sort key attorno a un attributo per poter interrogare gli Item nel suo ordine — poi l'attributo cambia. Lo status di un ticket, lo stato di un ordine, la priorità di un task. Ecco l'inghippo che ti riserva DynamoDB: non puoi aggiornare un attributo chiave sul posto. Una chiave primaria è immutabile per tutta la vita dell'Item. Cambia un valore che fa parte della chiave e non stai modificando un Item — lo stai spostando, cosa che DynamoDB ti obbliga a fare in modo esplicito.

Si può modificare una sort key di DynamoDB?

No. La sort key fa parte della chiave primaria e gli attributi chiave di DynamoDB sono immutabili — UpdateItem non può modificare un valore di partition key o sort key e non esiste un'operazione di «spostamento Item». Per cambiarlo, elimina il vecchio Item e scrivi uno nuovo, oppure tieni il valore volatile su una sort key di una GSI anziché sulla chiave della tabella di base.

  • Gli attributi chiave sono immutabili. Non puoi fare UpdateItem su un valore di partition key o sort key — DynamoDB non ha un'operazione di «spostamento Item».
  • Per cambiare il valore di una chiave elimini il vecchio Item e ne scrivi uno nuovo — idealmente in una transazione così è atomica.
  • Meglio: tieni il valore volatile fuori dalla chiave della tabella di base e mettilo invece su una sort key di una GSI — le chiavi delle GSI possono cambiare, perché aggiornare l'Item di base ri-propaga semplicemente la voce dell'indice.
  • Scegli sort key che non cambiano (timestamp, id immutabili) ogni volta che il pattern di accesso lo consente.

Il problema: uno status su cui vuoi ordinare, che continua a cambiare

Supponi di gestire un help desk e di voler elencare i ticket di un team ordinati per status, quindi metti lo status nella sort key:

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

Ora il ticket passa a pending. Vorresti semplicemente fare UpdateItem sulla sort key portandola a STATUS#pending#TICKET#8842 — ma DynamoDB rifiuta qualsiasi scrittura che cambi un attributo chiave. La chiave è l'indirizzo dell'Item; non puoi modificare l'indirizzo sul posto. Lo status che hai scelto per ordinare è esattamente la cosa che non sta ferma.

Opzione 1: elimina e ricrea (atomicamente)

Se il valore deve vivere nella chiave della tabella di base, cambiarlo significa rimuovere il vecchio Item e scriverne uno nuovo:

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

Fallo dentro un TransactWriteItems così il delete e il put o riescono entrambi o falliscono entrambi — altrimenti un crash tra i due perde il ticket o lo duplica. Funziona, ma ogni cambio di status ora è due scritture più una transazione; va bene per cambi occasionali, costoso per quelli frequenti.

Opzione 2: tieni il valore mutabile fuori dalla chiave di base (preferita)

Il design più pulito: rendi la chiave della tabella di base qualcosa di immutabile (l'id del ticket) e metti il valore volatile e ordinabile su una sort key di una GSI.

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

Ora cambiare lo status è un semplice UpdateItem sull'attributo status dell'Item di base — cosa che DynamoDB consente, perché status non è una chiave della tabella di base. DynamoDB poi ri-propaga automaticamente la voce della GSI nella sua nuova posizione ordinata. Una scrittura, nessuna transazione, nessun balletto di delete.

YesNo, it's a GSI sort keyStatus changes open to pendingIs the value in a base-table key?Delete + recreate in a transactionPlain UpdateItem; GSIre-propagates

Il compromesso: la GSI è eventualmente coerente e costa archiviazione/scritture extra — ma per un valore che cambia spesso, è molto più economico di delete-and-recreate a ogni cambio.

Progettare le chiavi in DynoTable

Costruisci e visualizza in anteprima le condizioni sulle chiavi sia per la lettura di base sia per la lettura della GSI nel generatore di espressioni DynamoDB.

In DynoTable scegli poi attraverso quale indice gira una query e osservi il valore volatile ordinarsi sulla GSI mentre l'Item di base mantiene la sua chiave immutabile — entrambe le letture fianco a fianco su dati reali.

Interrogare una GSI ordinata per status mentre l'Item di base mantiene una chiave immutabile in DynoTable.
Interrogare una GSI ordinata per status mentre l'Item di base mantiene una chiave immutabile in DynoTable.

Trappole e prossimi passi

  • Non provare mai a fare UpdateItem su un attributo chiave — viene rifiutato; i valori delle chiavi sono fissi per la vita dell'Item.
  • Se devi spostarlo, fai delete+put in una transazione — mai come due scritture non protette.
  • Preferisci chiavi di base immutabili + una GSI per qualsiasi attributo su cui ordini e che muti.
  • Non dimenticare la coerenza eventuale della GSI — la voce riordinata compare dopo un breve ritardo di propagazione.
  • Correlati: strategie per le sort key, GSI vs LSI, transazioni.

Vuoi vedere come un attributo mutabile si ordina su una GSI rispetto alla tabella di base? Scarica DynoTable ed esplora i tuoi indici direttamente.

Aggiornato