Relazioni uno-a-molti in DynamoDB
Un piano di controllo SaaS ha quasi sempre una gerarchia di contenimento: uno spazio di lavoro
possiede molti progetti. In SQL inseriresti una chiave esterna workspace_id sul file
tabella dei progetti e "JOIN".
DynamoDB non ha join né chiavi esterne, quindi la relazione deve vivere nel file
schema chiave stesso. Fatto bene, "carica uno spazio di lavoro e ogni progetto al suo interno"
diventa un singolo Query invece di una lettura più una scansione di follow-up.
Come si modella una relazione uno-a-molti in DynamoDB?
Date lo stesso al genitore e a tutti i suoi figliquindi ne condividono uno, quindi differenziarli con la chiave di ordinamento. DynamoDB non ha join o chiavi esterne, quindi la relazione risiede nello schema di chiavi stesso. Il caricamento di un genitore più ogni figlio diventa quindi un singolo Query invece di un join.
- Modella le letture, non le entità. Esiste solo la relazione uno-a-molti per servire "elenca i progetti di uno spazio di lavoro": modella le chiavi attorno a quella query.
- Codifica il genitore in quello del figlio. Dare lo spazio di lavoro e tutto il resto proietta lo stesso valore della chiave di partizione in modo che arrivino in uno .
- Quindi la lista letta è una
Query. Ritornano il genitore più i suoi figli insieme: nessuna unione, nessun secondo round trip (unQueryrestituisce fino a 1 MB per pagina, impaginazione tramite "LastEvaluatedKey" oltre). - Guarda il. Un enorme inquilino concentra tutto il tuo traffico su uno solo partizione; uno spazio di lavoro gigantesco potrebbe aver bisogno di una chiave frammentata e di una lettura a ventaglio.
Innanzitutto il modello di accesso
La modellazione DynamoDB è basata innanzitutto sul modello di accesso, non sull'entità: la stessa disciplina dietro design a tabella singola. Prima di sceglierne uno qualsiasi chiave, annota le letture effettivamente emesse dall'app:
- Ottieni le impostazioni di uno spazio di lavoro.
- Elenca tutti i progetti in uno spazio di lavoro, iniziando dal più recente.
- Ottieni un progetto specifico per ID.
La relazione "uno spazio di lavoro, molti progetti" è importante solo a causa della lettura n. 2. Se non avessi mai bisogno di elencare insieme i progetti di uno spazio di lavoro, non faresti il modello la relazione in generale: memorizzeresti i progetti in modo indipendente.
Quindi la domanda non è mai "come rappresento uno-a-molti?" in astratto. Lo è "quali domande deve servire questa relazione?" Rispondi, quindi modella le chiavi attorno ad esso.
Perché una chiave esterna non aiuta in questo caso
In DynamoDB ogni GetItem e Query ha come target una chiave di partizione, e la
Il servizio esegue l'hashing di quella chiave per individuare la partizione che contiene l'elemento.
AWS lo dice direttamente nei Componenti principali docs: il valore della chiave di partizione è l'input per una funzione hash interna che decide dove risiedono i dati.
Questo posizionamento basato su hash è l'eredità dell'originale Dynamo del 2007: Carta Store di valore-chiave altamente disponibile di Amazon, in cui hashing coerente distribuisce le chiavi tra i nodi.
Un semplice attributo workspace_id su un elemento del progetto è invisibile a questo
macchinario - DynamoDB non può "seguirlo".
Per recuperare elementi correlati in una richiesta, è necessario codificare l'identità del genitore
la chiave di partizione del progetto, in modo che tutti gli elementi di uno spazio di lavoro abbiano lo stesso hash
partizione e un Query può spazzarli.
Esempio realizzato: spazi di lavoro e progetti
Utilizzare uno schema di chiavi generico e sovraccaricato. Chiama la chiave di partizione "EntityRef" e il file chiave di ordinamento "Dettaglio". L'identità dello spazio di lavoro va in "EntityRef" per entrambi i file elemento dell'area di lavoro e ogni progetto sotto di esso:
| EntityRef | Detail | attributes |
|---|---|---|
| WS#acme | META | displayName, region, seatLimit |
| WS#acme | PROJ#2026-0007 | title, status, createdBy |
| WS#acme | PROJ#2026-0042 | title, status, createdBy |
| WS#acme | PROJ#2026-0118 | title, status, createdBy |
| WS#globex | META | displayName, region, seatLimit |
| WS#globex | PROJ#2026-0009 | title, status, createdBy |
Lo spazio di lavoro e tutti i suoi progetti condividono EntityRef = "WS#acme", quindi formano un file
singola collezione di oggetti che convivono su un unico divisorio.
La chiave di ordinamento "Detail" li separa: "META" è il record dell'area di lavoro e ciascuno project porta un prefisso "PROJ#" con un ID ordinato in base al tempo con riempimento zero, quindi progetti ordinare in modo naturale.
Visivamente, il genitore e i suoi figli si impilano all'interno di una partizione, ordinata da chiave di ordinamento:
Un Query su EntityRef = "WS#acme" spazza l'intero stack: genitore più ogni
bambino - in una sola lettura.
Ora i tre modelli di accesso si riducono ciascuno a una chiamata:
- Impostazioni dell'area di lavoro —
GetItem(EntityRef="WS#acme", Detail="META"). - Elenca progetti dal più recente al primo —
Query(EntityRef="WS#acme")conDettaglio begins_with "PROJ#", eseguito in ordine decrescente (ScanIndiceAvanti = false). - Un progetto —
GetItem(EntityRef="WS#acme", Detail="PROJ#2026-0042").
Il secondo è il punto. Il genitore e i suoi figli tornano da
uno Query, nessun join e nessun secondo andata e ritorno — DynamoDB restituisce fino a 1 MB
per pagina e ti fornisce un LastEvaluatedKey per recuperare il resto. Questa è la mossa
non puoi farlo con un attributo di chiave esterna e un Scan.
Scrivere a mano la condizione begins_with è complicato: la condizione chiave e
morsi della sintassi di proiezione-espressione.
Il DynamoDB Expression Builder genera
le mappe segnaposto KeyConditionExpression, #name/:value e un
Snippet SDK pronto per l'esecuzione in modo da non combattere la grammatica:
KeyConditionExpression "#er = :er AND begins_with(#d, :p)"
ExpressionAttributeNames { "#er": "EntityRef", "#d": "Detail" }
ExpressionAttributeValues { ":er": "WS#acme", ":p": "PROJ#" }
Esamina la raccolta di oggetti in DynoTable
Ogni riga che condivide un "EntityRef" è il file spazio di lavoro più i suoi figli, seduti uno accanto all'altro.
DynoTable li raggruppa in modo da vedere la relazione uno-a-molti come una contigua bloccare invece di indovinarlo su tabelle separate.

Le insidie e la forma alternativa
Alcune cose da guardare:
- Partizioni attive. Ogni elemento di uno spazio di lavoro risiede su una partizione, quindi a
un singolo inquilino molto grande o molto occupato concentra il traffico. Il
capacità adattiva
comportamento AWS descrive assorbe un'inclinazione moderata, ma uno spazio di lavoro con milioni di
i progetti potrebbero richiedere una chiave frammentata (ad esempio
WS#acme#01 … #10) e una lettura fan-out. - Dimensione della raccolta di elementi. Con un indice secondario locale, una singola partizione la raccolta di elementi è limitata a 10 GB; senza un LSI non esiste tale limite. Se stai valutando i tipi di indice qui, vedi GSI vs LSI.
- Raggiungi
Query, maiScan. L'intero design esiste in modo che tu possaQueryuna partizione. Ritornando a unScanfiltrato per "trovare uno spazio di lavoro progetti" getta via il modello e legge l'intera tabella: la trappola è coperta in Query vs Scan.
Se hai davvero bisogno di elencare i progetti tra gli spazi di lavoro (ad esempio, all
status = ACTIVE progetti a livello globale), la tabella di base non può rispondere: è
la chiave di partizione ha ambito nell'area di lavoro.
Questo è un lavoro per un indice secondario che ripartiziona i progetti su un altro attributo, non per rimodellare questa relazione.
Passaggi successivi
Modella i modelli di accesso, codifica il genitore nella chiave di partizione del figlio e
la lettura uno-a-molti è un singolo Query. Costruisci e convalida la condizione chiave
con DynamoDB Expression Builder — e
se preferisci iniziare dai modelli di accesso stessi, il free
Strumento di progettazione a tabella singola disegna il
Piano PK/SK/GSI con elementi di esempio.
Quindi download DynoTable per caricare questo schema, sfoglia il file
workspace→proietta la raccolta di elementi in tempo reale e conferma che ogni query ne esegue esattamente una
leggere. Se preferisci vedere gli spazi di lavoro e i progetti come una visione congiunta e relazionale,
DynoTable's SQL Workbench esegue anche quel JOIN.


