Como contar, somar e agregar em DynamoDB
DynamoDB tem exatamente um agregado integrado: contar itens correspondentes com
Selecione=CONTAR. Não há SUM, AVG, MIN ou MAX nativos. E até a contagem
você pode obter leituras (e cobranças) de cada item contado. Este guia cobre o que é
realmente suportado, as aproximações que as pessoas alcançam e como executar
COUNT/SUM/AVG em uma tabela quando você precisar deles.
DynamoDB pode fazer SUM, COUNT e funções agregadas?
Principalmente não. O único agregado integrado de DynamoDB é Select=COUNT, que retorna contagens de itens correspondentes, mas ainda lê (e cobra) cada item. Não há nenhum SUM, AVG, MIN ou MAX nativo, e PartiQL também não adiciona nenhum. Para agregados reais com GROUP BY, dobre-os em seu aplicativo, mantenha um contador ou execute SQL no Workbench de DynoTable.
Select=COUNTretorna o número de itens correspondentes, mas DynamoDB ainda lê cada item para produzi-lo - você paga o custo total de leituraScan/Query, não um custo barato de "contagem".- Não há operações de leitura nativas
SUM,AVG,MINouMAX. DynamoDB devolver itens; eles não os dobram em um número. PartiQL não adiciona agregados também. DescribeTable.ItemCounté gratuito, mas apenas aproximado e atualizado "aproximadamente a cada seis horas" — bom para um bloco de painel, errado para qualquer coisa exato.- Para
COUNT/SUM/AVG/MIN/MAXexato (comGROUP BY), agregue em seu app, mantenha um contador ou execute-o no SQL Workbench de DynoTable (abaixo).
Contando itens: Select=COUNT
Ambos Query e Scan aceitam um parâmetro Select. Defina-o como COUNT e o
resposta carrega as contagens em vez dos itens:
aws dynamodb scan \
--table-name Orders \
--select COUNT \
--filter-expression "#s = :open" \
--expression-attribute-names '{"#s":"status"}' \
--expression-attribute-values '{":open":{"S":"OPEN"}}'A resposta fornece dois números (AWS: Contando os itens nos resultados):
Count— "o número de itens que permanecem, após uma expressão de filtro (se presente) foi aplicado."ScannedCount— "o número de itens avaliados, antes de qualquerScanFilteré aplicado." Sem filtro,ScannedCounté o mesmo queCount.
Se você tiver apenas oe precisa contar duplicatas dentro dele, o
condição + filtro que você passa é exatamente o que
DynamoDB Expression Builder gera — o
Mapas FilterExpression e ExpressionAttributeNames/Values acima, mais o
KeyConditionExpression quando você conta dentro de uma partição via Query — sem
escapando manualmente do JSON.
Mais duas pegadinhas que mordem as pessoas contando mesas grandes:
- O limite de página de 1 MB ainda se aplica. "Se o tamanho do conjunto de resultados
Scanfor maior que 1 MB,ScannedCounteCountrepresentam apenas uma contagem parcial de o total de itens" (documentos AWS Scan). Você precisa paginar alimentandoLastEvaluatedKeyde cada resposta como oExclusiveStartKeyda próxima solicitação, mantendo um total em execução para obter o real número - o mesmo loop coberto em paginação DynamoDB. - Um
Queryestreito vence umScan.Select=COUNTem umQuerymede apenas o itens na partição de destino, não na tabela inteira. Se você pode fixar uma partição chave (tabela base ou GSI), conte lá - é o Query-vs-Scan lacuna de custo aplicada à contagem.
Select=COUNT vs ItemCount (e por que está obsoleto)
DescribeTable retorna um ItemCount (e TableSizeBytes) gratuitamente, sem
custo de leitura. O problema está no
API faz referência a si mesmo:
"DynamoDB atualiza este valor aproximadamente a cada seis horas. Mudanças recentes podem não
ser refletido neste valor." Portanto, pode ficar bem atrás do estado real da sua tabela.
Selecionar=CONTAR | DescribeTable.ItemCount | |
|---|---|---|
| Exatidão | Exato (para o conjunto correspondente) | Aproximado |
| Frescura | Ao vivo | Atualizado ~a cada 6 horas |
| Custo | Lê + fatura cada item contado | Grátis (metadados) |
| Pode filtrar/contar um subconjunto | Sim (expressão de filtro) | Não — apenas tabela inteira |
Use ItemCount para uma verificação aproximada de "qual o tamanho desta tabela" ou um bloco do painel.
Use Select=COUNT quando precisar de um número exato, filtrado ou atual — e aceite
o custo de leitura. Para qualquer coisa verdadeiramente viva e gratuita, monitore você mesmo um contador
(veja Padrões de agregação abaixo).
Por que não existe SUM/AVG/MIN/MAX nativo
As operações de leitura de DynamoDB retornam itens. Não há planejador de consultas para dobrar um resultado
definido em um escalar, então não há nada para calcular um SUM ou AVG. Contar é
a única dobra que API oferece, via Select=COUNT.
PartiQL não muda isso. O
PartiQL gramática SELECT
é SELECT {{expression}} [,…] FROM {{table}}[.{{index}}] [WHERE…] [ORDER BY {{key}} …],
onde a expressão é "uma projeção formada a partir do curinga * ou uma projeção
lista de um ou mais nomes de atributos ou caminhos de documentos." Não há agregado
função e nenhuma cláusula GROUP BY nessa gramática - e ORDER BY leva uma {{key}},
documentado como "uma chave hash ou uma chave de classificação a ser usada para ordenar os resultados retornados". Cada
PartiQL SELECT ainda compila para um GetItem, Query ou Scan, então
SELECT SUM(total) FROM "Orders" simplesmente não pode ser expresso. (Mais sobre o PartiQL
teto em PartiQL vs SQL.)
Padrões de agregação (contadores, fluxos, lado do aplicativo)
Como DynamoDB não agregará para você, os padrões estabelecidos impulsionam o trabalho em outro lugar:
- Item de contador mantido. Mantenha um item dedicado (por exemplo,
PK = "STATS#orders") eADDa um atributo numérico em cada gravação com umUpdateItem. Lendo o agregado é então um únicoGetItem- exato e barato, mas você possui o incremento lógica, sua consistência e a contenção se um contra-ataque for derrotado. - alimentando um agregador. Habilite um stream e conecte-o a um Lambda que
atualiza totais em execução (contagens, somas) à medida que os itens mudam. De acordo com
AWS Documentos de streams,
você pode configurar o
StreamViewTypedo stream para que cada registro carregue oNEW_AND_OLD_IMAGES— "as imagens novas e antigas do item" — o suficiente para manter os agregados no estiloSUMatualizados sem nova verificação. Os registros de fluxo estão sujeitos para uma vida útil de 24 horas ("os registros de fluxo dentro de um fragmento são removidos automaticamente após 24 horas"), então o consumidor tem que acompanhar. - Dobra no lado do aplicativo. Percorra os itens correspondentes e acumule os
SUM/AVG/MIN/MAXem seu próprio código. Correto, mas lê (e cobra) cada item sempre — o mesmo perfil de custo deSelect=COUNT, mais os dados transferência. - Descarregue para análise. Para agregação analítica pesada ou ad hoc, exporte o tabela para o S3 e consultá-la com o Athena ou transmiti-la para um warehouse. De acordo com documentos AWS exportar para S3, exportar "não consome unidades de capacidade de leitura" e permite "realizar análises e consultas complexas usando serviços AWS como Athena" — o caminho recomendado por AWS uma vez você superou a agregação por solicitação.
Cada um troca simplicidade por escrituração contábil em tempo de gravação (contadores, fluxos) ou
custo do tempo de leitura (verificações do lado do aplicativo). Nenhum padrão faz com que o próprio DynamoDB calcule uma SUM
de graça. A versão de agrupamento desta compensação - agregar por chave em vez de
sobre toda a mesa - é o seu próprio guia:
DynamoDB GROUP BY.
Executando COUNT/SUM/AVG em DynoTable's SQL Workbench
Quando você só precisa da resposta - "quantos pedidos ABERTOS e qual é o total" -
sem escrever um loop de varredura de paginação ou um Lambda, DynoTable's SQL Workbench
executa agregados reais. Ele materializa suas tabelas através do real DynamoDB
Query/Scan tempo de execução e, em seguida, executa um único SELECT no topo - agregados, GROUP BY,
HAVING, DISTINCT: SQL dentro das regras de padrão de acesso de 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 DESCIsso é COUNT, SUM, AVG, MIN, MAX, GROUP BY e ORDER BY em um
agregado computado - nenhum dos quais DynamoDB ou PartiQL pode expressar (PartiQL's
ORDER BY é limitado aos atributos-chave) - em uma instrução. Isto é o mesmo
cunha analítica como SQL para DynamoDB; para o completo
história de agrupamento, consulte DynamoDB GROUP BY.
O Workbench é honesto sobre o modelo de acesso abaixo, não um falso Postgres:
- As linhas ainda passam pelo Query/Scan real de DynamoDB. Um
GROUP BYsobre um todo tabela ainda é umScanembaixo - as superfícies Workbench que custam em vez de escondendo-o, a mesma compensação Query-vs-Scan. - As agregações são executadas nos atributos escalares materializados depois que as linhas chegam.
FAQ
Posso contar itens em DynamoDB sem digitalizar?
Não exatamente. Para uma contagem exata e atual, você deve ler os itens -
Select=COUNT ainda mede cada item contado. As únicas opções sem digitalização são as
DescribeTable.ItemCount aproximado (atualizado ~a cada 6 horas) ou um item de contador que você
mantenha-se em cada gravação.
Como posso contar itens por GSI?
Execute Query (ou Scan) no índice com Select=COUNT. Contando através de um
partição estreita GSI é muito mais barata do que escanear a tabela base, porque você só
leia os itens nessa partição de índice – modele o índice em torno da contagem necessária.
O DescribeTable.ItemCount é preciso?
É aproximado. O
Referência API
afirma que DynamoDB atualiza ItemCount e TableSizeBytes "aproximadamente a cada seis
horas" e "as alterações recentes podem não estar refletidas neste valor". Não use onde
um número exato ou real é importante.
O DynamoDB pode fazer SUM ou AVG?
Não nativamente, e não em PartiQL — o
PartiQL gramática SELECT
não tem funções agregadas. Agregue na sua aplicação, mantenha um contador
(opcionalmente via DynamoDB Streams), ou execute SUM/AVG em DynoTable's SQL
Workbench.
Qual é a diferença entre Count e ScannedCount?
ScannedCount é quantos itens DynamoDB avaliados antes do seu filtro; Contar é
quantos permanecem depois disso. Eles são iguais quando não há expressão de filtro. Um grande
a lacuna entre eles significa uma contagem ineficiente.
Precisa somar, calcular a média ou agrupar seus dados DynamoDB sem escrever um loop de varredura? Baixe DynoTable e execute-o em uma aba Workbench. Comparando clientes primeiro? Veja onde ele chega em uma GUI DynamoDB simples.