Intermedio8 min di lettura

Strategie per le sort key di DynamoDB

Una chiave primaria DynamoDB è uno o due attributi: una partition key da sola, o una partition key più una sort key. La partition key decide quale partizione fisica contiene un item.

La sort key decide l'ordine degli item all'interno di quella partizione — e quell'ordinamento è ciò che rende potente Query.

Scegli la sort key sbagliata e puoi comunque scrivere dati, ma perdi le letture per intervalli, l'ordinamento e diversi access pattern da un'unica collection.

Venendo da SQL ricorreresti a un ORDER BY o a un secondary index dopo il fatto. In DynamoDB inforni l'ordine nella chiave fin dall'inizio, oppure non lo ottieni.

Come funzionano le sort key di DynamoDB?

Una sort key di DynamoDB ordina gli item all'interno di una partizione, così che Query possa effettuare letture per intervalli — >=, between, begins_with — invece di recuperare un item alla volta. L'ordinamento è byte-order sulla chiave codificata, quindi progettala (un timestamp ISO-8601, un numero riempito con zeri) in modo che il byte-order corrisponda all'ordine in cui vuoi leggere.

  • La sort key è il tuo indice intra-partizione. Ordina la item collection su disco, così che Query possa fare letture per intervalli (>=, between, begins_with) invece di un singolo GetItem.
  • L'ordinamento è byte-order sulla chiave codificata. Progetta la chiave così che il byte-order eguagli l'ordine in cui vuoi leggere — un timestamp ISO-8601, un numero riempito con zeri, mai un UUID grezzo o 6/23/2026.
  • Una sort key ben modellata serve molti access pattern. Una chiave composta (EVT#<timestamp>) è prefisso e intervallo insieme — nessuna GSI necessaria.
  • La direzione è gratis. ScanIndexForward = false legge dal più recente allo stesso costo; non memorizzare timestamp invertiti per fingerlo.

Perché la sort key è la leva

Senza una sort key, ogni item in una partizione è indirizzabile solo dalla sua chiave primaria completa — un GetItem al meglio. Aggiungi una sort key e DynamoDB memorizza gli item ordinati per essa all'interno della partizione, cosa che sblocca Query.

Ciò significa condizioni per intervalli (>=, between), confronto di prefissi (begins_with) e un flag ScanIndexForward per leggere in ordine crescente o decrescente.

Secondo la AWS DynamoDB Developer Guide, tutti gli item che condividono una partition key formano una item collection, ordinata su disco dalla sort key.

Quindi la sort key non è solo un secondo identificatore. È l'indice contro cui interroghi all'interno di una partizione.

Quell'ordinamento è byte-order sulla sort key codificata: le stringhe si confrontano per byte UTF-8, i numeri si confrontano numericamente. Questo unico fatto guida quasi ogni strategia qui sotto.

Se vuoi che le query per intervalli significhino qualcosa, il byte-order deve corrispondere all'ordine in cui vuoi leggere.

Strategia 1: rendi la sort key ordinabile

L'errore più comune è una sort key che non è ordinata in modo significativo. Un UUID casuale ti dà unicità ma nessuna query per intervalli utile — "dammi gli ultimi 20" diventa impossibile perché il byte-order è arbitrario.

Codifica invece il valore su cui ordini e filtri dentro la sort key, in una rappresentazione il cui byte-order eguagli il suo ordine logico. Per i timestamp ciò significa un formato lessicograficamente ordinabile: una stringa ISO-8601 o un epoch riempito con zeri.

ISO-8601 è stato progettato così che il confronto tra stringhe eguagli il confronto cronologico — esattamente ciò di cui ha bisogno una query per intervalli. Evita formati come 6/23/2026; si ordinano male nel momento in cui il mese cambia.

Se ordini su numeri (un contatore di versione, un punteggio), usa il tipo nativo Number di DynamoDB invece di una stringa, così 42 si ordina dopo 9 invece che prima.

Se un numero deve vivere dentro una sort key composta di tipo stringa, riempilo con zeri a una larghezza fissa.

Strategia 2: sort key composte per la gerarchia

Una sort key può codificare una gerarchia concatenando segmenti con un delimitatore, più comunemente #. Una sola condizione begins_with seleziona allora un intero sotto-albero:

SK
EVENT#2026-06#01#login
EVENT#2026-06#03#export
EVENT#2026-07#02#login

begins_with(SK, "EVENT#2026-06#") restituisce solo gli eventi di giugno; il più ampio begins_with(SK, "EVENT#") li restituisce tutti.

L'ordine dei segmenti è una decisione di design. Da grezzo a fine (anno → mese → giorno) mantiene contigui gli item correlati, così una lettura per intervalli resta una query economica invece di una dispersione attraverso la partizione.

Strategia 3: controlla la direzione con ScanIndexForward

DynamoDB memorizza gli item in ordine crescente di sort key e li legge così per default. Per leggere dal più recente — l'ordine naturale per un feed di attività — imposta ScanIndexForward = false sulla Query.

Questo è un flag di lettura, non una decisione di schema: la stessa collection serve entrambe le direzioni allo stesso costo. Non invertire i tuoi timestamp (memorizzando un "reverse epoch") solo per ottenere letture decrescenti.

Una item collection, memorizzata una volta in ordine crescente, letta in entrambi i versi:

ScanIndexForward = trueScanIndexForward = falseItem collection (una PK)SK EVT#09:00SK EVT#14:00SK EVT#giorno-dopoDal più vecchioDal più recente

Stessi item, stessa partizione, stesso costo — cambia solo la direzione di lettura.

L'unica eccezione: se hai bisogno specificamente che l'ordine decrescente sia anche l'ordine in cui avanza un indice sparso o un cursore di paginazione. A meno di ciò, ScanIndexForward è la leva più semplice.

Esempio pratico: un log di audit per attore

Supponi di registrare eventi con timestamp prodotti da attori — utenti, servizi, chiavi API — in un prodotto SaaS, e di avere due letture:

  1. Lo stream di attività di un attore, dall'evento più recente.
  2. Gli eventi di un attore in una finestra temporale (es. "tutto tra i due deploy"), per un'indagine.

Entrambe le letture sono limitate a un singolo attore, quindi l'attore è la partition key e l'ora dell'evento è la sort key. Usa nomi di chiave generici così che la stessa tabella possa contenere altre entità in seguito:

PKSKattributes
ACTOR#u_8814EVT#2026-06-23T09:12:04Zaction=login, ip, ua
ACTOR#u_8814EVT#2026-06-23T14:05:11Zaction=export, target
ACTOR#u_8814EVT#2026-06-24T08:40:55Zaction=login, ip, ua
ACTOR#svc_billingEVT#2026-06-23T00:00:00Zaction=invoice.run

Il prefisso EVT# più un timestamp ISO-8601 dà una sort key ordinabile. La lettura 1 è Query PK = "ACTOR#u_8814" con ScanIndexForward = false per partire dal più recente. La lettura 2 restringe la stessa partizione con una condizione between sulla sort key:

Query
PK = "ACTOR#u_8814"
AND SK BETWEEN "EVT#2026-06-23T00:00:00Z"
AND "EVT#2026-06-23T23:59:59Z"

Una collection, due access pattern, nessuna GSI — perché la sort key è sia un prefisso (EVT#) sia un intervallo (il timestamp). La lettura decrescente e la lettura per finestra sono gli stessi item nello stesso ordine; cambiano solo i parametri.

Costruendo quella key condition a mano, è facile sbagliare i limiti di between o l'escape delle parole riservate sui nomi degli attributi.

Il DynamoDB Expression Builder genera la KeyConditionExpression, gli ExpressionAttributeNames e gli ExpressionAttributeValues per una condizione sort-key begins_with o between.

Copiala dritta nella tua chiamata SDK invece di debuggare l'escape a runtime.

Fallo in DynoTable

Progettare una sort key è iterativo: scrivi qualche item rappresentativo, esegui la query per intervalli e controlla che le righe tornino nell'ordine che ti aspetti. Farlo contro una tabella dal vivo in una GUI batte il round-trip attraverso il codice.

Interrogazione della collection di log di audit di un attore in DynoTable con una condizione between sulla sort key, risultati ordinati dal più recente.
Interrogazione della collection di log di audit di un attore in DynoTable con una condizione between sulla sort key, risultati ordinati dal più recente.

Inverti la direzione di ordinamento, stringi i limiti di between e guarda la collection restituita cambiare senza scrivere una riga di codice — il modo più rapido per confermare un design di sort key prima di committarlo.

Trappole e prossimi passi

  • Le sort key devono essere uniche all'interno di una partizione. Se due eventi possono condividere un timestamp, aggiungi un disambiguatore (un numero di sequenza o un id breve) alla sort key così che la composta resti unica.
  • Una hot partition non si può aggirare con l'ordinamento. Se un attore produce molti più eventi degli altri, la sort key non ti salverà — ti serve un design di partition key che distribuisca il carico. Vedi single-table design.
  • Un secondo ordine di sort richiede un secondo indice. La sort key della tabella base dà un ordinamento. Per ordinare gli stessi item in modo diverso (per tipo di evento, diciamo), aggiungi una GSI con una sort key diversa — pesando i compromessi local vs global secondary index.
  • Non ricorrere a Scan per "ordinare dopo". Ordinare lato client dopo uno Scan legge l'intera tabella e butta via l'ordinamento; è il footgun dello Scan. Spingi invece l'ordine nella sort key.

Una volta che la key condition è giusta, prova DynoTable per modellare la collection, eseguire le query crescenti e decrescenti fianco a fianco e verificare la tua strategia di sort key contro dati reali prima che vada in produzione.

Aggiornato