Chave Primária Composta no DynamoDB
Uma chave primária composta são dois atributos: uma chave de partição e uma chave de classificação. A chave de partição decide onde um item vive; a chave de classificação ordena os itens dentro daquela partição.
Vindo do SQL, pense nela menos como uma coluna id única e mais como
GROUP BY partition, ORDER BY sort embutido na própria tabela.
O que é uma chave primária composta no DynamoDB?
Uma chave primária composta no DynamoDB combina dois atributos: uma chave de partição e uma 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 daquela partição. Juntas, elas formam a identidade única do item e permitem que um único Query retorne um intervalo ordenado em vez de um único item.
- Duas partes, dois trabalhos. A chave de partição roteia o item para uma partição física; a chave de classificação ordena todo item que compartilha aquela chave de partição.
- A unicidade é o par. Dois itens podem compartilhar um valor de chave de partição desde que suas chaves de classificação difiram — é assim que uma partição contém muitas linhas.
- A chave de classificação é o objetivo todo. É o que deixa um
Queryretornar um intervalo (>=,between,begins_with) em vez de um item, semScan. - Chaves precisam ser escalares. Chaves de partição e classificação só podem ser string, número ou binário — sem mapas, sem listas (documentação AWS).
Chave simples vs chave composta
Uma chave primária simples é só uma chave de partição. Ela identifica unicamente um
item, e você a lê de volta com GetItem. É isso — sem leituras de intervalo, sem
"me dê os N mais novos".
Uma chave composta adiciona a chave de classificação, e essa única adição é o que faz o DynamoDB parecer um banco de dados em vez de um hash map.
| Chave simples | Chave composta | |
|---|---|---|
| Atributos | Apenas chave de partição | Chave de partição + chave de classificação |
| Unicidade | Valor da chave de partição | O par de valores |
| Múltiplos itens por partição | Não | Sim |
Query de um intervalo | Não (só GetItem) | Sim (begins_with, between, >) |
| Encaixe natural | Busca por id | Série temporal, um-para-muitos, histórico |
Modele uma tabela de leituras de sensores
Digamos que você colete amostras de temperatura de uma frota de sensores de campo. O padrão de acesso é "pegue as leituras de um dispositivo, mais novas primeiro, dentro de uma janela de tempo". Isso é uma chave composta de manual.
Use o id do dispositivo como chave de partição e o timestamp da leitura como chave de classificação:
| deviceId | readingTs | tempC | humidity |
|---|---|---|---|
| DEV#a1b2 | 2026-06-23T08:00:00Z | 21.4 | 48 |
| DEV#a1b2 | 2026-06-23T08:05:00Z | 21.7 | 47 |
| DEV#a1b2 | 2026-06-23T08:10:00Z | 22.1 | 46 |
| DEV#c9d8 | 2026-06-23T08:00:00Z | 19.8 | 55 |
Todas as três leituras de DEV#a1b2 caem na mesma partição, fisicamente armazenadas
juntas e ordenadas por readingTs.
A AWS chama a chave de partição de atributo de hash e a chave de classificação de atributo de intervalo — a chave de classificação é um intervalo dentro do qual você pode varrer (documentação AWS).
Eis como os itens colapsam em uma coleção de itens sob cada chave de partição:
Um Query contra a chave de partição lê toda leitura daquele dispositivo, já em ordem
de timestamp — sem ordenação no cliente, sem segunda ida e volta.
Consulte o intervalo, não faça scan nele
Como readingTs é uma string ISO-8601, ela ordena lexicograficamente do mesmo jeito
que ordena cronologicamente. Então uma leitura de janela de tempo é um intervalo de
condição de chave, não um filtro:
Query
deviceId = "DEV#a1b2"
readingTs BETWEEN "2026-06-23T08:00:00Z" AND "2026-06-23T08:10:00Z"
Essa é uma KeyConditionExpression — ela estreita a leitura antes de o DynamoDB
retornar dados, então você paga apenas pelos itens da janela. Uma FilterExpression
roda depois da leitura e te cobra por tudo que ela varreu; essa é a
cilada do Scan em miniatura.
A expressão em si, com placeholders e valores tipados, é chata de escrever à mão.
Monte-a visualmente com o
DynamoDB Expression Builder e copie a
KeyConditionExpression exata para a sua chamada de SDK.
Projete a chave de classificação de propósito
A chave de classificação não é metadado grátis — é a única alavanca para leituras de intervalo, então molde-a às suas consultas.
- Use um timestamp ordenável. Strings ISO-8601 ou números epoch com zero-padding ordenam corretamente; datas localizadas cruas não.
- Prefixe-a para sobrecarga um-para-muitos. Uma chave de classificação como
READING#2026-06-23T08:00:00Zdeixa você misturar tipos de entidade sob uma partição e fatiá-los combegins_with. Essa é a costura para o single-table design. - Coloque a dimensão de alta cardinalidade na chave de partição. O id do sensor tem
milhares de valores, então espalha as escritas uniformemente. Uma chave de partição
de baixa cardinalidade (digamos,
region) cria uma partição quente.
Quando uma chave composta te morde
É um compromisso, não uma conveniência. A cilada: você escolhe uma chave de partição, lança, depois descobre um padrão de acesso que precisa de um agrupamento diferente — "todas as leituras acima de 30°C em toda a frota".
A tabela base não consegue responder isso; a chave de partição é fixa. Suas opções são um global secondary index com uma chave diferente, ou reestruturação.
Enumere suas leituras antes de comprometer o schema de chaves. Mudar uma chave
primária significa uma migração de tabela, não um ALTER TABLE.
Próximos passos
Chaves compostas são a fundação sob coleções de itens, relacionamentos um-para-muitos e a maioria dos designs úteis de índice — leia single-table design e GSI vs LSI em seguida para ver aonde elas levam.
Esboce sua KeyConditionExpression no
DynamoDB Expression Builder, depois
experimente o DynoTable para navegar nas suas partições reais e ver a
ordem de classificação se alinhar contra suas próprias tabelas.