Iniciante8 min de leitura

Chave primária composta DynamoDB: partição + chave de classificação explicada

Uma chave primária composta consiste em dois atributos: uma chave de partição e uma chave de classificação. A chave de partição decide onde um item reside; a chave de classificação ordena itens dentro dessa partição.

Vindo do SQL, pense nele menos como uma coluna id exclusiva e mais como GROUP BY partition, ORDER BY sort embutido na própria mesa.

O que é uma chave primária composta DynamoDB?

Uma chave primária composta DynamoDB combina dois atributos: uma chave de partição e um chave de classificação. A chave de partição decide em qual partição física um item reside; a chave de classificação ordena os itens dentro dessa partição. Juntos eles formam o item identidade única e permitir que um único Query retorne um intervalo classificado em vez de um item.

  • Duas partes, dois trabalhos. A chave de partição encaminha o item para um local físico partição; a chave de classificação ordena cada item que compartilha essa chave de partição.
  • Singularidade é o par. Dois itens podem compartilhar um valor de chave de partição, desde que como suas chaves de classificação são diferentes - é assim que uma partição contém muitas linhas.
  • A chave de classificação é o ponto principal. É o que permite que um Query retorne um intervalo (>=, between, begins_with) em vez de um item, sem Scan.
  • As chaves devem ser escalares. As chaves de partição e classificação só podem ser string, número, ou binário - sem mapas, sem listas (documentos AWS).

Chave simples vs chave composta

Uma chave primária simples é apenas uma chave de partição. Ele identifica exclusivamente um item, e você o lê de volta com GetItem. É isso aí - sem leituras de intervalo, não "dê-me o N mais novo".

Uma chave composta adiciona a chave de classificação, e essa única adição é o que torna DynamoDB parece um banco de dados em vez de um mapa hash.

Chave simplesChave composta
AtributosApenas chave de partiçãoChave de partição + chave de classificação
SingularidadeValor da chave de partiçãoO par de valores
Vários itens por partiçãoNãoSim
Query uma gamaNão (somente GetItem)Sim (begins_with, between, >)
Ajuste naturalPesquisa por idSérie temporal, um para muitos, história

Modele uma tabela de leituras de sensores

Digamos que você colete amostras de temperatura de uma frota de sensores de campo. O acesso padrão é "obter as leituras de um dispositivo, o mais novo primeiro, dentro de um período de tempo janela". Essa é uma chave composta de livro didático.

Use o ID do dispositivo como chave de partição e o carimbo de data/hora de leitura como chave de classificação:

deviceIdreadingTstempChumidity
DEV#a1b22026-06-23T08:00:00Z21.448
DEV#a1b22026-06-23T08:05:00Z21.747
DEV#a1b22026-06-23T08:10:00Z22.146
DEV#c9d82026-06-23T08:00:00Z19.855

Todas as três leituras DEV#a1b2 ficam na mesma partição, armazenadas fisicamente juntos e classificados por readingTs.

AWS chama a chave de partição de atributo hash e a chave de classificação de intervalo atributo — a chave de classificação é um intervalo que você pode verificar (documentos AWS).

Os itens são recolhidos em um em cada partição chave:

Partição: DEV#a1b2leituraTs 08:00leituraTs 08:05leituraTs 08:10Consulta deviceId = DEV#a1b2

Um Query na chave de partição lê todas as leituras desse dispositivo, já em ordem de carimbo de data e hora - sem classificação no cliente, sem segunda viagem de ida e volta.

Quanto custa essa janela

Dez leituras de 2 KB cada na partição somam 20 KB medidos. Rodadas DynamoDB lê por bloco de 4 KB, portanto, um Query eventualmente consistente nessa janela custa 3 unidades de solicitação de leitura (20 KB → cinco blocos de 4 KB × 0,5 RCU cada). Um leitura fortemente consistente na mesma janela custa 5 unidades (uma RCU por bloco). Busque as mesmas dez linhas com dez chamadas GetItem separadas e o mínimo de um bloco a regra se aplica por item → 5 unidades eventualmente consistentes, 10 fortemente consistente – antes de contar viagens extras de ida e volta.

Padrão de leituraItensDados tocadosUnidades de leitura CE
Um Query, readingTs entre início e fim1020 KB3
10 × GetItem em chave composta completa1020 KB5
Somente partição Query, filtro de umidade no aplicativo1020 KB3
Tabela Scan, filtro deviceId + janela de tempotudomesa inteiratamanho de mesa

Passe ReturnConsumedCapacity: TOTAL durante a prototipagem; o calculadora de preços transforma essa contagem de unidades em um item de linha mensal quando você conhece as solicitações por segundo.

Consulte o intervalo, não o verifique

Como readingTs é uma string ISO-8601, ela classifica lexicograficamente da mesma forma maneira como ele classifica cronologicamente. Portanto, uma leitura de janela de tempo é um intervalo de condições-chave, não é um filtro:

Query
deviceId  = "DEV#a1b2"
readingTs BETWEEN "2026-06-23T08:00:00Z" AND "2026-06-23T08:10:00Z"

Esse é um KeyConditionExpression - restringe a leitura antes do DynamoDB retorna dados, então você paga apenas pelos itens da janela. Um FilterExpression executa após a leitura e cobra por tudo o que foi digitalizado; isso é o Scan footgun em miniatura.

A expressão em si, com espaços reservados e valores digitados, é complicada de escrever manualmente. Construa-o visualmente com o DynamoDB Expression Builder e copie o exato KeyConditionExpression em sua chamada SDK.

Projete a chave de classificação propositalmente

A chave de classificação é a única alavanca para leituras de intervalo, então moldá-lo de acordo com suas dúvidas.

  • Use um carimbo de data/hora classificável. Strings ISO-8601 ou números de época classificar corretamente; datas localizadas brutas não.
  • Prefixe-o para um para muitos. Uma chave de classificação como READING#2026-06-23T08:00:00Z permite misturar tipos de entidade em uma partição e corte-os com begins_with. Essa é a costura em design de mesa única.
  • Coloque a dimensão de alta cardinalidade na chave de partição. O ID do sensor possui milhares de valores, por isso distribui as escritas uniformemente. Uma partição de baixa cardinalidade chave (digamos, region) cria um .

Uma chave de partição com apenas cinquenta valores distintos em uma taxa de 10.000 escritas por segundo stream concentra ~200 WCU por partição lógica antes da divisão do DynamoDB - bom em escala de protótipo, doloroso em escala de produção. Prefira identificadores que crescer com sua frota (ID do dispositivo, ID do locatário, ID da sessão) em agrupamentos grosseiros a menos que você coloque deliberadamente um conjunto de dados limitado.

Quando uma chave composta te morde

As chaves compostas são um compromisso. Você escolhe uma chave de partição, envia, então descubra um padrão de acesso que precisa de um agrupamento diferente - "todos leituras acima de 30°C em toda a frota".

A tabela base não pode responder a isso; a chave de partição é fixa. Suas opções são um índice secundário global com uma chave diferente, ou reestruturação.

Enumere suas leituras antes de confirmar o esquema de chave. Alterando uma chave primária significa uma migração de tabela, não um ALTER TABLE.

No DynoTable, abra o navegador de tabelas e inspecione uma tabela de chave composta lado a lado lado com seus GSIs - a ordem de classificação na chave de classificação é visível linha por linha, o que torna óbvios os formatos de carimbo de data / hora off-by-one antes de chegarem à produção.

Próximos passos

As chaves compostas são a base das coleções de itens, um para muitos relacionamentos e designs de índice mais úteis - leia design de mesa única e GSI vs LSI a seguir para ver aonde eles levam.

Esboce seu KeyConditionExpression no DynamoDB Expression Builder, emita o arquivo completo Query paginado no construtor de consultas, então experimente DynoTable para navegar em suas partições reais e observar a classificação ordene a fila em suas próprias mesas.

Atualizado