Intermedio5 min di lettura

Composite Sort Key in DynamoDB

Una composite primary key è una chiave di partizione più una sort key. Il trucco che la rende potente è ciò che metti dentro la sort key: codifica una gerarchia come un'unica stringa delimitata, e una sola Query legge un intero sottoalbero in ordine di sort — niente join, niente ricorsione, nessun secondo round-trip.

Come funzionano le composite sort key in DynamoDB?

Una composite sort key impacchetta una gerarchia in un'unica stringa delimitata — root/photos/2026/ — che DynamoDB memorizza in ordine di byte UTF-8. Poiché il layout corrisponde già all'albero, una sola Query con begins_with(SK, "root/photos/") legge un intero sottoalbero in ordine di percorso. Niente join, niente ricorsione, nessun secondo round-trip — solo una scansione per prefisso su una fetta contigua.

  • La sort key è una stringa ordinabile, non solo un ID. Impacchettaci dentro un percorso — root/photos/2026/ — e DynamoDB memorizza gli Item della partizione in ordine di byte UTF-8 automaticamente.
  • Un delimitatore trasforma i match per prefisso in letture di sottoalbero. begins_with(SK, "root/photos/") restituisce ogni discendente di quella cartella in una sola query.
  • Le sort key supportano condizioni di range, non filtri arbitrari. Hai begins_with, between, >, < — progetta la chiave così che la lettura che ti serve sia un prefisso o un range, non uno Scan.
  • Il delimitatore è portante. Scegline uno che non possa comparire in un segmento di percorso, altrimenti due rami non correlati collidono.

Perché la sort key è tutto il gioco

Venendo da SQL, modelleresti un albero di cartelle con un self-join su parent_id e lo percorreresti ricorsivamente — una query per livello. In DynamoDB quello è un footgun N+1 contro uno store chiave-valore che non ha join.

DynamoDB memorizza ogni Item sotto una chiave di partizione ordinato per la sua sort key, in ordine di byte UTF-8 per le stringhe (AWS: Query key conditions). Quindi se la tua sort key è il percorso, il layout fisico corrisponde già all'albero. Una lettura diventa una scansione per prefisso su una fetta contigua — non una camminata su grafo.

Questo è il cambio: la sort key non è un identificatore che abbini esattamente. È un indirizzo ordinabile. Progettala e la query ne deriva gratis.

Modella un albero di file system

Diciamo che stai memorizzando alberi di file per account. Un drive per account è la partizione naturale; il percorso al suo interno è la sort key.

PKSKnode_typebytes
DRIVE#a91root/folder-
DRIVE#a91root/photos/folder-
DRIVE#a91root/photos/2026/folder-
DRIVE#a91root/photos/2026/beach.jpgfile284910
DRIVE#a91root/photos/2026/sunset.jpgfile512004
DRIVE#a91root/docs/folder-
DRIVE#a91root/docs/taxes.pdffile88210

Due convenzioni originali fanno il lavoro qui:

  • PK = DRIVE#<account> tiene l'intero albero di un account in un'unica item collection, così ogni lettura di sottoalbero è una Query su singola partizione.
  • SK è il percorso completo con uno / finale sulle cartelle. Lo slash finale è deliberato — fa ordinare una cartella prima dei propri figli e tiene root/photos/ distinto da un file fratello chiamato root/photos.

Leggi un sottoalbero in una sola query

Elenca tutto sotto root/photos/ — cartella, sottocartelle e file, ricorsivamente:

Query
KeyConditionExpression = PK = :drive AND begins_with(SK, :prefix)
:drive   = "DRIVE#a91"
:prefix  = "root/photos/"

Questo restituisce root/photos/, root/photos/2026/, beach.jpg e sunset.jpg — in ordine di percorso, in una sola lettura fatturata. Paghi solo per gli Item in quella fetta, non per l'intero drive.

In DynoTable, esegui esattamente questa query begins_with sulla sort key di percorso e la cartella insieme ai suoi discendenti torna in ordine di percorso — senza dover scrivere a mano la sintassi dei placeholder.

Hai bisogno del KeyConditionExpression grezzo (nomi, valori e begins_with) per il tuo codice? Costruiscilo e copialo nel DynamoDB Expression Builder.

Esecuzione di una query begins_with sulla sort key di percorso in DynoTable, che restituisce una cartella e i suoi discendenti in ordine di percorso.
Esecuzione di una query begins_with sulla sort key di percorso in DynoTable, che restituisce una cartella e i suoi discendenti in ordine di percorso.

Elenca un livello, non l'intero sottoalbero

begins_with ti dà la lettura ricorsiva. Per un listing di directory non ricorsivo — i figli immediati di root/photos/ e niente di più profondo — memorizza un attributo depth e aggiungi un range sulla sort key più un filtro, oppure dividi il percorso in un GSI parent. La versione più semplice: tieni un attributo parent (root/photos/) e un GSI con chiave su di esso.

Il punto: una sort key risponde a domande di prefisso e range a basso costo. "Solo i figli diretti" è una domanda diversa — modellala esplicitamente invece di sperare che una FilterExpression la renda efficiente. Un filtro gira dopo la lettura e paghi per ogni Item che scarta.

Scegli il delimitatore con cura

Il delimitatore è parte del tuo contratto dati. Due regole:

  • Non deve mai comparire dentro un segmento di percorso. Se i nomi di file possono contenere /, / è il delimitatore sbagliato — un file chiamato a/b è indistinguibile da una cartella a che contiene b. Scegli un byte riservato (alcuni team usano # o un control char) e vietalo nei segmenti.
  • Attenzione all'ordine di sort ai confini. / (0x2F) si ordina prima di cifre e lettere, che di solito è ciò che vuoi per l'ordine dell'albero. Cambia il delimitatore e cambi l'ordinamento — verificalo su dati reali.

Composite sort key vs. attributo di sort separato

Composite sort key (root/photos/2026/x)Sort key con ID semplice + attributo parent
Lettura sottoalberoUna query begins_withQuery ricorsive (N+1) o camminata su GSI
OrdinamentoOrdine di percorso, gratisDevi aggiungere un attributo di sort esplicito
Spostamento / rinominaRiscrivi tutti i discendentiAggiorna un puntatore parent
Elenco figli direttiServe attributo depth o GSINaturale (parent = x)

Le composite key vincono quando le letture hanno forma a sottoalbero e l'ordinamento conta; il modello a ID piatto vince quando l'albero muta di continuo. La maggior parte delle gerarchie a prevalenza letture — alberi di file, alberi di categorie, organigrammi — pende verso le composite.

Errori e prossimi passi

  • Non sovraccaricare la chiave. Tutto ciò che codifichi è immutabile e indicizzato per solo prefisso. Gli attributi che interroghi per uguaglianza appartengono ai loro campi o a un GSI, non incastrati nella sort key.
  • Una sort key non può fare un WHERE arbitrario. Solo begins_with, between e confronti. Se ti ritrovi a reggiungere una FilterExpression, probabilmente hai modellato la chiave male — vedi Query vs. Scan.
  • L'approfondimento sul design delle chiavi sta in single-table design; per quando una lettura di sottoalbero ha bisogno di un indice invece della tabella base, vedi GSI vs. LSI.

Costruisci la key condition begins_with con l' Expression Builder, poi scarica DynoTable per eseguire queste query per prefisso sulle tue tabelle e osservare un sottoalbero tornare in ordine di percorso.

Aggiornato