Principiante9 min di lettura

Come CONTARE, SOMMA e aggregare in DynamoDB

DynamoDB ha esattamente un aggregato integrato: contare gli elementi abbinati con Seleziona=COUNT. Non esistono "SUM", "AVG", "MIN" o "MAX" nativi. E anche il conteggio tu puoi ricevere letture (e fatture per) ogni articolo contato. Questa guida spiega di cosa si tratta effettivamente supportato, le approssimazioni che le persone raggiungono e come funzionare in modo reale COUNT/SUM/AVG su una tabella quando ne hai bisogno.

Può DynamoDB eseguire funzioni SUM, COUNT e aggregate?

Per lo più no. L'unico aggregato integrato di DynamoDB è Select=COUNT, che restituisce il conteggio degli articoli corrispondenti ma legge comunque (e fattura) ogni articolo. Non esistono SUM, AVG, MIN o MAX nativi e nemmeno PartiQL ne aggiunge nessuno. Per aggregati reali con GROUP BY, inseriscili nella tua app, mantieni un contatore o esegui SQL in DynoTable Workbench.

  • Select=COUNT restituisce il numero di elementi corrispondenti, ma DynamoDB continua a leggere ogni oggetto per produrlo: paghi l'intero costo di lettura Scan/Query, non un costo "conteggio" economico.
  • Non esistono SUM, AVG, MIN o MAX nativi. Operazioni di lettura di DynamoDB restituire articoli; non li piegano in un numero. PartiQL non aggiunge aggregati neanche.
  • DescribeTable.ItemCount è gratuito ma solo approssimativo e aggiornato "circa ogni sei ore": va bene per un riquadro del dashboard, sbagliato per qualsiasi cosa esatto.
  • Per COUNT/SUM/AVG/MIN/MAX esatto (con GROUP BY), aggrega nel tuo app, mantieni un contatore o eseguilo in DynoTable di SQL Workbench (sotto).

Conteggio degli elementi: Seleziona=COUNT

Sia Query che Scan accettano un parametro Select. Impostalo su "COUNT" e il file la risposta riporta i conteggi anziché gli elementi:

aws dynamodb scan \
  --table-name Orders \
  --select COUNT \
  --filter-expression "#s = :open" \
  --expression-attribute-names '{"#s":"status"}' \
  --expression-attribute-values '{":open":{"S":"OPEN"}}'

La risposta fornisce due numeri (AWS: conteggio degli elementi nei risultati):

  • Count — "il numero di elementi che rimangono, dopo un'espressione di filtro (if presente) è stato applicato."
  • ScannedCount — "il numero di elementi valutati, prima di qualsiasi ScanFilter viene applicato." Senza filtro, ScannedCount è uguale a Count.

Se hai solo ile devi contare i duplicati al suo interno, the condizione + filtro che passi è esattamente ciò che DynamoDB Expression Builder genera: il Le mappe FilterExpression e ExpressionAttributeNames/Values sopra, più le mappe KeyConditionExpression quando conti all'interno di una partizione tramite Query — senza scappando a mano da JSON.

Altri due trucchi che tormentano le persone che contano tabelle grandi:

  • Si applica ancora il limite di pagina di 1 MB. "Se la dimensione del set di risultati Scan è maggiore di 1 MB, ScannedCount e Count rappresentano solo un conteggio parziale di il totale degli articoli" (documenti AWS Scan). Devi impaginare reimmettendo LastEvaluatedKey di ciascuna risposta come file la richiesta successiva ExclusiveStartKey, mantenendo un totale progressivo per ottenere quello reale numero: lo stesso ciclo trattato in DynamoDB impaginazione.
  • Un Query stretto batte un Scan. Seleziona=COUNT su un Query misura solo il elementi nella partizione di destinazione, non nell'intera tabella. Se riesci a bloccare una partizione chiave (tabella base o GSI), conta lì: è il Query-vs-Scan divario di costo applicato al conteggio.

Select=COUNT vs ItemCount (e perché è obsoleto)

DescribeTable restituisce un ItemCount (e TableSizeBytes) gratuitamente, senza leggere il costo. Il problema sta nel API riferimento stesso: "DynamoDB aggiorna questo valore circa ogni sei ore. Le modifiche recenti potrebbero non farlo riflettersi in questo valore." Quindi può essere molto indietro rispetto allo stato attuale del tuo tabella.

Seleziona=COUNT"DescribeTable.ItemCount"
EsattezzaEsatto (per l'insieme abbinato)Approssimativo
FreschezzaDal vivoAggiornato ~ ogni 6 ore
CostoLegge + fattura ogni articolo conteggiatoGratuito (metadati)
Può filtrare/contare un sottoinsiemeSì (espressione filtro)No, solo l'intera tabella

Utilizza "ItemCount" per un controllo approssimativo di "quanto è grande questa tabella" o per un riquadro del dashboard. Utilizza "Seleziona=COUNT" quando hai bisogno di un numero esatto, filtrato o corrente e accetta il costo di lettura. Per qualsiasi cosa veramente viva e gratuita, traccia tu stesso un contatore (vedi Modelli di aggregazione di seguito).

Perché non esiste SUM/AVG/MIN/MAX nativo

Le operazioni di lettura di DynamoDB restituiscono elementi. Non esiste un pianificatore di query per ridurre un risultato impostato in uno scalare, quindi non c'è nulla con cui calcolare una "SOMMA" o un "AVG". Contare è l'unica piega offerta da API, tramite Select=COUNT.

PartiQL non cambia questo. Il PartiQL Grammatica SELECT è SELECT {{espressione}} [, …] FROM {{tabella}}[.{{indice}}] [WHERE …] [ORDER BY {{chiave}} …], dove l'espressione è "una proiezione formata dal carattere jolly * o da una proiezione elenco di uno o più nomi di attributi o percorsi di documenti." Non esiste alcun aggregato funzione e nessuna clausola GROUP BY in quella grammatica — e ORDER BY accetta un {{key}}, documentato come "una chiave hash o una chiave di ordinamento da utilizzare per ordinare i risultati restituiti". Ogni PartiQL SELECT viene comunque compilato in GetItem, Query o Scan, quindi SELECT SUM(total) FROM "Orders" semplicemente non è esprimibile. (Maggiori informazioni su PartiQL soffitto in PartiQL vs SQL.)

Modelli di aggregazione (contatori, flussi, lato app)

Poiché DynamoDB non si aggregherà per te, i modelli stabiliti spingono il lavoro altrove:

  • Contatore mantenuto. Mantieni un elemento dedicato (ad esempio PK = "STATS#orders") e ADD a un attributo numerico su ogni scrittura con un UpdateItem. Leggendo il l'aggregato è quindi un singolo GetItem: esatto ed economico, ma l'incremento è tuo logica, la tua coerenza e la contesa se un contatore viene martellato. -alimentando un aggregatore. Abilita un flusso e collegalo a un Lambda that aggiorna i totali parziali (conteggi, somme) man mano che gli elementi cambiano. Secondo il AWS Documenti sui flussi, puoi configurare il StreamViewType del flusso in modo che ogni record contenga il file NEW_AND_OLD_IMAGES — "sia la nuova che la vecchia immagine dell'articolo" — sufficiente per mantenere aggiornati gli aggregati in stile "SUM" senza ripetere la scansione. I record di flusso sono soggetti a una durata di 24 ore ("i record di flusso all'interno di uno shard vengono rimossi automaticamente dopo 24 ore"), quindi il consumatore deve tenere il passo.
  • Piegatura lato app. Sfoglia gli elementi abbinati e accumula i SUM/AVG/MIN/MAX nel tuo codice. Corretto, ma si legge (e fattura) ogni articolo ogni volta: lo stesso profilo di costo di "Seleziona=COUNT", più i dati trasferimento.
  • Scarica in analisi. Per aggregazioni analitiche pesanti o ad hoc, esporta il file table su S3 ed interrogarlo con Athena, oppure trasmetterlo in streaming in un magazzino. Secondo il AWS documenti di esportazione in S3, l'esportazione "non consuma unità di capacità di lettura" e consente di "eseguire analisi e query complesse che utilizzano servizi AWS come Athena" — il percorso consigliato da AWS una volta hai superato l'aggregazione per richiesta.

Ciascuno scambia la semplicità con la contabilità del tempo di scrittura (contatori, flussi) o costo del tempo di lettura (scansioni lato app). Nessun modello fa sì che DynamoDB stesso calcoli una SUM gratuitamente. La versione di raggruppamento di questo compromesso: aggregazione per chiave anziché sull'intera tabella - è la propria guida: DynamoDB GRUPPO BY.

Esecuzione di COUNT/SUM/AVG in DynoTable SQL Workbench

Quando hai solo bisogno della risposta — "quanti ordini APERTI e qual è il loro totale" — senza scrivere un ciclo di scansione di impaginazione o un Lambda, SQL Workbench di DynoTable esegue aggregati reali. Materializza le tue tabelle attraverso l'effettivo di DynamoDB Query/Scan runtime, quindi esegue un singolo SELECT in alto — aggregati, GROUP BY, HAVING, DISTINCT: SQL entro le regole del modello di accesso di DynamoDB.

-- Runs in the DynoTable Workbench (NOT in PartiQL):
SELECT status,
       COUNT(*)        AS orders,
       SUM(total)      AS revenue,
       AVG(total)      AS avg_order,
       MIN(total)      AS smallest,
       MAX(total)      AS largest
FROM orders
GROUP BY status
ORDER BY revenue DESC

Sono "COUNT", "SUM", "AVG", "MIN", "MAX", "GROUP BY" e "ORDER BY" su un aggregato calcolato - nessuno dei quali DynamoDB o PartiQL può esprimere (di PartiQL "ORDER BY" è limitato agli attributi chiave) - in un'unica istruzione. Questo è lo stesso cuneo analitico come SQL for DynamoDB; per intero raggruppamento della storia vedere DynamoDB GROUP BY.

Il Workbench è onesto riguardo al modello di accesso sottostante, non un finto Postgres:

  • Le righe passano ancora attraverso il vero Query/Scan di DynamoDB. Un "GROUP BY" nel suo insieme la tabella è ancora un Scan sotto: le superfici Workbench che costano anziché nascondendolo, lo stesso compromesso Query-vs-Scan.
  • Gli aggregati vengono eseguiti sugli attributi scalari materializzati dopo l'atterraggio delle righe.

FAQ

Posso contare gli elementi in DynamoDB senza eseguire la scansione? Non esattamente. Per un conteggio esatto e aggiornato è necessario leggere gli elementi: Select=COUNT misura comunque ogni elemento contato. Le uniche opzioni senza scansione sono approssimativo DescribeTable.ItemCount (aggiornato ~ ogni 6 ore) o un contatore che hai mantieniti su ogni scrittura.

Come faccio a contare gli elementi per GSI? Esegui Query (o Scan) rispetto all'indice con Select=COUNT. Conteggio tramite a la partizione stretta GSI è molto più economica della scansione della tabella di base, perché solo tu leggi gli elementi in quella partizione dell'indice: modella l'indice attorno al conteggio che ti serve.

DescribeTable.ItemCount è accurato? È approssimativo. Il Riferimento API afferma DynamoDB aggiorna ItemCount e TableSizeBytes "circa ogni sei ore" e "le modifiche recenti potrebbero non riflettersi in questo valore". Non usarlo dove un numero esatto o vivo è importante.

DynamoDB può eseguire SUM o AVG? Non in modo nativo, e non in PartiQL — il PartiQL Grammatica SELECT non ha funzioni aggregate. Aggrega nella tua applicazione, mantieni un contatore (opzionalmente tramite DynamoDB Streams), oppure esegui SUM/AVG in DynoTable SQL Workbench.

Qual è la differenza tra Count e ScannedCount? ScannedCount è il numero di elementi DynamoDB valutati prima del filtro; "Conte" è quanti ne rimangono dopo. Sono uguali quando non è presente alcuna espressione di filtro. Un grande il divario tra loro significa un conteggio inefficiente.


Hai bisogno di sommare, calcolare la media o raggruppare i tuoi dati DynamoDB senza scrivere un ciclo di scansione? Scarica DynoTable ed eseguilo in una scheda Workbench. Confronto tra i clienti prima? Scopri dove si posiziona contro una semplice GUI DynamoDB.

Aggiornato