Intermedio4 min di lettura

Single-table design in DynamoDB

Venendo da SQL, l'istinto è una tabella per entità: customers, orders, order_items. In DynamoDB quell'istinto è di solito sbagliato. Una singola tabella che memorizza ogni entità, distinta da prefissi di chiave sovraccaricati, ti permette di recuperare un genitore e i suoi figli in una sola Query — niente join, niente N+1.

Parti dai pattern di accesso, non dalle entità

Il single-table design è access-pattern-first. Prima di scegliere una singola chiave, annota ogni lettura che la tua app fa — "ottieni il profilo di un cliente", "elenca gli ordini di un cliente dal più recente", "trova tutti gli ordini aperti" — perché le chiavi esistono solo per servire quell'elenco. La normalizzazione relazionale ottimizza l'archiviazione; la modellazione DynamoDB ottimizza le query che già sai di dover eseguire. Enumerale, poi progetta le chiavi perché ognuna sia una singola Query.

L'idea

Scegli nomi di chiave generici (PK, SK) e codifica il tipo di entità nel valore:

PKSKattributes
CUSTOMER#42PROFILEname, email, plan
CUSTOMER#42ORDER#2026-001total, status
CUSTOMER#42ORDER#2026-002total, status

Ora una Query PK = "CUSTOMER#42" restituisce il profilo e ogni ordine in una singola lettura fatturata. SK begins_with "ORDER#" la restringe ai soli ordini.

Visivamente, gli Item sovraccaricati si impilano sotto un'unica partition key come una singola collezione di Item:

Partition: CUSTOMER#42SK: PROFILESK: ORDER#2026-001SK: ORDER#2026-002One Query

Una sola lettura della partizione restituisce il cliente e ogni ordine insieme.

GSI sovraccaricati

Lo stesso trucco funziona sugli indici. Metti un GSI1PK/GSI1SK generico sugli Item, e un singolo GSI serve più pattern di accesso a seconda di cosa ogni Item scrive in quegli attributi:

PKSKGSI1PKGSI1SK
ORDER#001METADATASTATUS#OPEN2026-01-04
ORDER#002METADATASTATUS#OPEN2026-01-05

Ora Query GSI1 WHERE GSI1PK = "STATUS#OPEN" elenca gli ordini aperti per data — un pattern a cui la tabella di base non può rispondere. Un'entità diversa può riutilizzare GSI1 con il proprio significato (es. CATEGORY#books). Un indice, molte query.

Molti-a-molti: la lista di adiacenza

Per le relazioni (un utente in molti team, un team con molti utenti), scrivi l'arco due volte con gli id scambiati: PK=USER#1, SK=TEAM#9 e PK=TEAM#9, SK=USER#1. Interrogare un lato elenca l'altro — il sostituto DynamoDB di una join table.

Quando non fare single-table

Non è gratis. Una tabella sovraccaricata è più difficile da ragionare, più difficile da evolvere e ostile all'analisi. Se i tuoi pattern di accesso sono davvero sconosciuti o cambiano costantemente, o i dati sono per lo più analitici, tabelle separate (o uno store diverso) possono essere la scelta più saggia. Il single-table vince quando i pattern sono noti e ad alto volume.

Costo della forma sbagliata

Modellare come tabelle separate forza uno Scan o un join lato client per ricomporre un cliente, e questo è il trabocchetto dello Scan. Modella prima i pattern di accesso, poi progetta le chiavi perché ognuno sia una Query.

Stima quanto costano questi Item per lettura con il calcolatore di dimensione e capacità degli Item, e prova DynoTable per sfogliare uno schema single-table e vedere le collezioni sovraccaricate affiancate.

Aggiornato