L'attributo Type in DynamoDB
In SQL, la tabella di una riga è il suo tipo — una riga in documents è un
documento. Una single table di DynamoDB mescola ogni entità sotto un unico
schema, quindi un item non porta con sé alcuna risposta intrinseca alla domanda
"cos'è questo?".
L'attributo Type rimette a posto quella risposta: una semplice stringa su ogni item che nomina l'entità che rappresenta.
Cos'è l'attributo Type in DynamoDB?
L'attributo Type è una semplice stringa che marchi su ogni item — come EntityType: "Document" — che nomina l'entità che quell'item rappresenta. Poiché una single table mescola molte entità sotto un unico schema, gli item non hanno un tipo incorporato. Il Type lo rimette a posto, così il tuo codice identifica le righe, filtra un GSI su una sola entità e sopravvive alle migrazioni.
- Marchia un Type a ogni scrittura. Un attributo —
EntityType: "Document"— su ogni item, senza eccezioni. Costa pochi byte e ti salva in seguito. - Identifica le entità in una partizione mista. Una
Queryrestituisce workspace, documenti e commenti insieme; il Type dice al tuo codice quale è quale senza analizzare i prefissi delle chiavi. - Abilita il filtraggio su singola entità in un GSI. Proietta il Type in un index e potrai restringere un index sovraccaricato a esattamente un tipo di entità.
- È la tua via di fuga per le migrazioni. Quando esporti per rimodellare o spostare un'entità nella sua tabella, il Type è la colonna su cui dividi.
Perché una tabella mista perde il tipo
Il single-table design memorizza ogni entità in
un'unica tabella dietro chiavi generiche come PK e SK. È proprio questo il
punto — una sola Query restituisce un genitore e i suoi figli insieme. Ma
significa che una partizione è eterogenea.
Prendi un'app SaaS di collaborazione sui documenti. Una partizione workspace contiene il record del workspace, i suoi documenti e i commenti su quei documenti:
| PK | SK | attributes |
|---|---|---|
| WS#acme | META | name, plan, seats |
| WS#acme | DOC#a1#META | title, owner, wordCount |
| WS#acme | DOC#a1#CMT#0007 | author, body, createdAt |
| WS#acme | DOC#a1#CMT#0008 | author, body, createdAt |
Query PK = "WS#acme" restituisce tutti e quattro gli item in una sola lettura
fatturata. Ora il tuo codice ha una lista di item grezzi e nessun modo
affidabile per dire quale è un documento e quale un commento — a meno di fare
string-matching sul SK, che è fragile nel momento in cui cambia il formato
delle tue chiavi.
Marchia il Type su ogni item
La soluzione è un attributo su ogni scrittura, che nomina l'entità:
| PK | SK | EntityType | title |
|---|---|---|---|
| WS#acme | META | Workspace | — |
| WS#acme | DOC#a1#META | Document | Q3 Roadmap |
| WS#acme | DOC#a1#CMT#0007 | Comment | — |
Ramificare su item.EntityType === "Document" è un controllo di uguaglianza
stabile. Analizzare SK.startsWith("DOC#") && SK.includes("#CMT#") è una
supposizione che si rompe quando aggiorni la chiave. Il Type disaccoppia la tua
logica di lettura dalla codifica delle chiavi — questo è il vero vantaggio.
Una sola lettura restituisce tre tipi di entità; l'attributo Type instrada ogni item al gestore corretto senza toccare le chiavi.
Filtra un GSI su una sola entità
Il Type si ripaga sugli index. Diciamo che aggiungi un GSI con chiavi
GSI1PK = WS#acme, GSI1SK = updatedAt per elencare "tutto ciò che è cambiato
di recente in questo workspace, dal più nuovo". Un index sovraccaricato raccoglie
documenti e commenti — ma una UI a feed potrebbe volere solo i documenti.
Due modi per restringerlo, e la differenza sono soldi:
| Approccio | Cosa costa | Quando usarlo |
|---|---|---|
FilterExpression sul Type | Legge tutti gli item corrispondenti, fattura tutti, scarta i non corrispondenti dopo la lettura | Le entità miste sono rare nel risultato; veloce da spedire |
Sparse index (Type in GSI1PK) | Solo l'entità che vuoi finisce mai nell'index | Una sola entità domina; vuoi zero spreco |
Una FilterExpression viene eseguita dopo che gli item sono letti e
dopo che la capacità è consumata — AWS è esplicito sul fatto che il
filtraggio non riduce il costo di lettura
(DynamoDB Developer Guide: FilterExpression).
Filtrare sul Type è onesto, non gratis: paghi per i commenti che butti via.
Per restringere il feed ai documenti, la query porta una condizione
sull'attributo Type. Assembla la FilterExpression, i nomi e i valori con
l'expression builder per DynamoDB — emette
il placeholder #t = :doc così non sbagli a digitare una parola riservata.
KeyConditionExpression GSI1PK = :ws
FilterExpression #t = :doc
ExpressionAttributeNames { "#t": "EntityType" }
ExpressionAttributeValues { ":ws": "WS#acme", ":doc": "Document" }
Vuoi che l'index porti solo documenti e salti del tutto il filtro? Scrivi
GSI1PK solo sugli item documento — uno sparse index.
Gli item senza la chiave del GSI non vengono mai replicati nell'index, quindi la
lettura tocca solo i documenti. L'attributo Type è ciò che dice al tuo writer
quali item si qualificano.
Mantieni il valore stabile e singolare
Scegli il valore una volta e trattalo come un enum. Document, mai a volte Doc
e a volte document — un valore che deriva è peggio di nessun valore, perché i
tuoi controlli di uguaglianza passano su una capitalizzazione e mancano
silenziosamente l'altra.
Un Type per item. Se un item sembra essere due entità, di solito è un odore di modellazione — dovrebbe essere due item, ciascuno nella propria collection o range di sort key, non una riga che indossa due cappelli.
Il dividendo della migrazione
La ragione per marchiare il Type prima di averne bisogno: il rimodellamento. Il percorso di rimodellamento raccomandato è esporta, trasforma, reimporta — e AWS documenta l'export di massa su S3 esattamente per questo tipo di rimodellamento offline (Esportare DynamoDB su S3).
Quando arriverà quel giorno, il Type è la colonna su cui fai GROUP BY. Vuoi
sollevare i commenti nella loro tabella, o rinormalizzare l'export in file
per-entità per un data warehouse di analytics? Dividi il dump su EntityType.
Senza, sei di nuovo a fare reverse engineering delle chiavi su milioni di righe.
Prossimi passi
L'attributo Type è un'assicurazione a basso costo: identifica le entità in una lettura mista, filtra un GSI sovraccaricato e dividi pulitamente quando rimodelli. Marchialo su ogni scrittura fin dal primo giorno — applicarlo retroattivamente a una tabella live significa un backfill completo.
Letture correlate: single-table design per il
pattern di partizione mista che questo serve, GSI vs LSI
per scegliere la forma di index dietro uno sparse index, e
Query vs Scan per capire perché una FilterExpression
non ti fa mai risparmiare costo di lettura.
Costruisci il filtro sul Type con l'expression builder per DynamoDB e prova DynoTable per sfogliare una vera tabella a entità miste e vedere la colonna Type allinearsi su ogni item.