Strategie di sort key in DynamoDB: 3 pattern e quando usarli
Una chiave primaria di DynamoDB è uno o due attributi: una da sola, oppure una chiave di partizione più una sort key. La chiave di partizione decide quale partizione fisica contiene un item.
La sort key decide l'ordine degli item dentro quella partizione — ed è quell'
ordinamento a rendere potente Query.
Scegli la sort key sbagliata e potrai comunque scrivere dati, ma perdi le letture su intervalli, l'ordinamento e diversi pattern di accesso da un'unica collezione.
Venendo da SQL ricorreresti a un ORDER BY o a un indice secondario dopo il
fatto. In DynamoDB cuoci l'ordine nella chiave fin da subito, oppure non lo ottieni.
Come funzionano le sort key di DynamoDB?
Una sort key di DynamoDB ordina gli item dentro una partizione, così che Query possa fare letture su intervalli — >=, between, begins_with — invece di recuperare un item alla volta. Le sort key di tipo String si ordinano per byte UTF-8 (i Number si ordinano numericamente), quindi progetta una chiave stringa (un timestamp ISO-8601, un numero con zero-padding) in modo che l'ordine dei byte coincida con l'ordine in cui vuoi leggere.
- La sort key è il tuo indice dentro la partizione. Ordina la su
disco, così che
Querypossa fare letture su intervalli (>=,between,begins_with) invece di un singoloGetItem. - Le sort key di tipo String si ordinano per byte UTF-8 (i Number si ordinano numericamente). Progetta una
chiave stringa in modo che l'ordine dei byte coincida con l'ordine in cui vuoi leggere — un timestamp
ISO-8601, un numero con zero-padding, mai un UUID grezzo o
6/23/2026. - Una sola sort key ben progettata serve molti pattern di accesso. Una
(
EVT#<timestamp>) è al contempo un prefisso e un intervallo — nessuna GSI necessaria. - La direzione è gratis.
ScanIndexForward = falselegge dal più recente allo stesso costo; non memorizzare timestamp invertiti per simularlo.
Perché la sort key è la leva
Senza una sort key, ogni item di una partizione è indirizzabile solo tramite la sua
chiave primaria completa — un GetItem nel migliore dei casi. Aggiungi una sort key e DynamoDB memorizza gli item
ordinati per essa dentro la partizione, il che sblocca Query.
Questo significa condizioni su intervalli (>=, between), corrispondenza di prefisso (begins_with),
e un flag ScanIndexForward per leggere in ordine crescente o decrescente.
Secondo l'AWS DynamoDB Developer Guide, tutti gli item che condividono una chiave di partizione formano una collezione di item, ordinata su disco per sort key.
Quindi la sort key non è solo un secondo identificatore. È l'indice su cui esegui le query dentro una partizione.
Quell'ordinamento è l'ordine dei byte 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 su intervalli abbiano un senso, l'ordine dei byte deve coincidere con l'ordine in cui vuoi leggere.
Strategia 1: rendi ordinabile la sort key
L'errore più comune è una sort key che non è ordinata in modo significativo. Un UUID casuale ti dà unicità ma nessuna query su intervalli utile — "dammi gli ultimi 20" diventa impossibile perché l'ordine dei byte è arbitrario.
Invece, codifica il valore su cui ordini e filtri dentro la sort key, in una rappresentazione il cui ordine dei byte coincida con il suo ordine logico. Per i timestamp questo significa un formato lessicograficamente ordinabile: una stringa ISO-8601 o un epoch con zero-padding.
ISO-8601 è stato progettato così che il confronto tra stringhe coincida con il confronto cronologico —
esattamente ciò di cui una query su intervalli ha bisogno. Evita formati come 6/23/2026; si ordinano male
nell'istante in cui il mese cambia.
Se ordini su numeri (un contatore di versione, un punteggio), usa il tipo Number nativo
di DynamoDB anziché una stringa, così che 42 si ordini dopo 9 invece che
prima.
Se un numero deve vivere dentro una sort key stringa composta, applicagli zero-padding a una larghezza fissa.
Strategia 2: sort key composte per la gerarchia
Una sort key può codificare una gerarchia concatenando segmenti con un delimitatore,
il più delle volte #. Una sola condizione begins_with seleziona allora un intero sottoalbero:
| 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'ordinamento dei segmenti è una decisione di progettazione. Dal grossolano al fine (anno → mese → giorno) mantiene gli item correlati contigui, così che una lettura su intervalli resti una query economica invece di uno sparpagliamento sulla partizione.
Strategia 3: controlla la direzione con ScanIndexForward
DynamoDB memorizza gli item in ordine di sort key crescente 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 collezione serve entrambe le direzioni allo stesso costo. Non invertire i tuoi timestamp (memorizzando un "reverse epoch") solo per ottenere letture decrescenti.
Una collezione di item, memorizzata una volta in ordine crescente, letta in entrambi i modi:
Stessi item, stessa partizione, stesso costo — cambia solo la direzione di lettura.
Esempio pratico: un audit log vincolato all'attore
Supponi di registrare eventi con timestamp prodotti da attori — utenti, servizi, API key — in un prodotto SaaS, e di avere due letture:
- Lo stream di attività per un attore, dall'evento più recente.
- Gli eventi di un attore in una finestra temporale (es. "tutto tra i due deploy"), per un'indagine.
Entrambe le letture sono vincolate a un singolo attore, quindi l'attore è la chiave di partizione e l'orario dell'evento è la sort key. Usa nomi di chiave generici così che la stessa tabella possa contenere altre entità in seguito:
| 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 |
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 avere il più recente prima. 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 collezione, due pattern di accesso, nessuna GSI — perché la sort key è al contempo un prefisso
(EVT#) e un intervallo (il timestamp). La lettura decrescente e la lettura sulla finestra sono
gli stessi item nello stesso ordine; cambiano solo i parametri.
Costruendo quella condizione di chiave a mano, è facile sbagliare i limiti del between o
l'escaping delle parole riservate sui nomi degli attributi.
Il DynamoDB Expression Builder
genera la KeyConditionExpression, gli ExpressionAttributeNames e i
ExpressionAttributeValues per una condizione di sort key begins_with o between.
Copiala dritta nella tua chiamata SDK invece di fare debug dell'escaping a runtime.
Fallo in DynoTable
Progettare una sort key è iterativo: scrivi qualche item rappresentativo, esegui la query su intervalli e verifica che le righe tornino nell'ordine che ti aspetti. Farlo su una tabella live in una GUI batte il round-trip attraverso il codice.

Inverti la direzione di ordinamento, stringi i limiti del between e osserva la
collezione restituita cambiare senza scrivere una riga di codice — il modo più veloce per confermare un
design di sort key prima di committarlo.
Insidie e passaggi successivi
- Le sort key devono essere uniche dentro 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 aggira con l'ordinamento. Se un attore produce molti più eventi degli altri, la sort key non ti salverà — ti serve un design della chiave di partizione che distribuisca il carico. Vedi single-table design.
- Un secondo ordinamento richiede un secondo indice. La sort key della tabella base dà un solo ordinamento. Per ordinare gli stessi item in modo diverso (per tipo di evento, ad esempio), aggiungi una GSI con una sort key diversa — soppesando i compromessi tra indice secondario locale e globale.
- Non ricorrere allo
Scanper "ordinare dopo". Ordinare lato client dopo unoScanlegge l'intera tabella e butta via l'ordinamento; è il trabocchetto dello Scan. Spingi invece l'ordine dentro la sort key.
Una volta che la condizione di chiave è corretta, prova DynoTable per modellare la collezione, eseguire fianco a fianco le query crescenti e decrescenti e verificare la tua strategia di sort key su dati reali prima che vada in produzione.


