Intermediário6 min de leitura

Chaves de classificação composta em DynamoDB

Um é uma chave de partição mais uma chave de classificação. O truque que o que o torna poderoso é o que você coloca na chave de classificação: codifique uma hierarquia como uma string delimitada e um único Query lê uma subárvore inteira em ordem de classificação - não junta-se, sem recursão, sem segunda viagem de ida e volta.

Como as chaves de classificação composta funcionam em DynamoDB?

Uma chave de classificação composta agrupa uma hierarquia em uma string delimitada — root/photos/2026/ — que DynamoDB armazena na ordem de bytes UTF-8. Como o layout já corresponde à árvore, um único Query com begins_with(SK, "root/photos/") lê uma subárvore inteira na ordem do caminho. Sem junções, sem recursão, sem segunda viagem de ida e volta - apenas uma varredura de prefixo em um local contíguo .

  • A chave de classificação é uma string classificável, não apenas um ID. Coloque um caminho nela — root/photos/2026/ — e DynamoDB armazena os itens da partição em byte UTF-8 faça o pedido automaticamente.
  • Um delimitador transforma correspondências de prefixo em leituras de subárvore. begins_with(SK, "root/photos/") retorna todos os descendentes dessa pasta em uma consulta.
  • As chaves de classificação suportam condições de intervalo, não filtros arbitrários. Você obtém begins_with, between, >, < — projete a chave para que a leitura que você precisa seja um prefixo ou intervalo, não um Scan.
  • O delimitador suporta carga. Escolha um que não possa aparecer em um segmento de caminho, ou dois ramos não relacionados colidem.

Por que a chave de classificação é o jogo inteiro

Vindo de SQL, você modelaria uma árvore de pastas com uma auto-junção parent_id e caminharia é recursivamente — uma consulta por nível. Em DynamoDB é uma arma de pé N+1 contra um armazenamento de valores-chave que não possui junções.

DynamoDB armazena todos os itens sob uma chave de partição classificada por sua chave de classificação, em UTF-8 ordem de bytes para strings (AWS: Query condições de chave). Portanto, se sua chave de classificação é o caminho, o layout físico já corresponde à árvore. Uma leitura torna-se uma varredura de prefixo em uma fatia contígua - não uma caminhada no gráfico.

Essa é a mudança: a chave de classificação não é um identificador que você corresponde exatamente. É um endereço classificável. Projete-o e a consulta será lançada de graça.

Modele uma árvore de sistema de arquivos

Digamos que você esteja armazenando árvores de arquivos por conta. Uma unidade por conta é o natural partição; o caminho dentro dele é a chave de classificação.

PKSKnode_typebytes
DRIVE#a91root/folder-
DRIVE#a91root/docs/folder-
DRIVE#a91root/docs/taxes.pdffile88210
DRIVE#a91root/photos/folder-
DRIVE#a91root/photos/2026/folder-
DRIVE#a91root/photos/2026/beach.jpgfile284910
DRIVE#a91root/photos/2026/sunset.jpgfile512004

Duas convenções originais fazendo o trabalho aqui:

  • PK = DRIVE#<account> mantém a árvore inteira de uma conta em uma única, portanto, qualquer leitura de subárvore é uma partição única Query.
  • SK é o caminho completo com um / final nas pastas. A barra final é deliberado - faz com que uma pasta seja classificada antes de seus próprios filhos e mantém root/photos/ distinto de um arquivo irmão chamado root/photos.

Leia uma subárvore em uma consulta

Liste tudo em root/photos/ — pasta, subpastas e arquivos, recursivamente:

Query
KeyConditionExpression = PK = :drive AND begins_with(SK, :prefix)
:drive   = "DRIVE#a91"
:prefix  = "root/photos/"

Isso retorna root/photos/, root/photos/2026/, beach.jpg e sunset.jpg — na ordem do caminho, em uma leitura faturada. Você paga apenas pelos itens dessa fatia, não toda a viagem.

Em DynoTable, você executa exatamente esta consulta begins_with na chave de classificação do caminho e no pasta mais seus descendentes voltam na ordem do caminho - nenhuma sintaxe de espaço reservado para escrever à mão.

Precisa do KeyConditionExpression bruto (nomes, valores e begins_with) para o seu próprio código? Construa e copie-o no DynamoDB Expression Builder.

Executando uma consulta begins_with na chave de classificação de caminho em DynoTable, retornando uma pasta e seus descendentes na ordem do caminho.
Executando uma consulta begins_with na chave de classificação de caminho em DynoTable, retornando uma pasta e seus descendentes na ordem do caminho.

Liste um nível, não a subárvore inteira

begins_with fornece a leitura recursiva. Para um diretório não recursivo listagem - os filhos imediatos de root/photos/ e nada mais profundo - armazena um profundidade e adicione um intervalo de chaves de classificação mais um filtro ou divida o caminho em um pai GSI. A versão mais simples: mantenha um atributo parent (root/photos/) e um GSI digitado nele.

Uma chave de classificação responde a perguntas de prefixo e intervalo de maneira barata. "Direto somente crianças" é uma questão diferente - modele-a explicitamente, em vez de esperar que FilterExpression torna-o eficiente. Um filtro é executado após a leitura e você paga para cada item que ele descarta.

Escolha o delimitador com cuidado

O delimitador faz parte do seu contrato de dados. Duas regras:

  • Ele nunca deve aparecer dentro de um segmento de caminho. Se nomes de arquivos puderem conter /, / é o delimitador errado — um arquivo chamado a/b é indistinguível de um pasta a segurando b. Escolha um byte reservado (algumas equipes usam # ou um controle char) e proibi-lo em segmentos.
  • Observe a ordem de classificação nos limites. / (0x2F) classifica antes dos dígitos e letras, que geralmente é o que você deseja para a ordem das árvores. Altere o delimitador e você altera a ordem – verifique-a com dados reais.

Chave de classificação composta versus um atributo de classificação separado

Chave de classificação composta (root/photos/2026/x)Chave de classificação de ID simples + atributo parent
Leitura de subárvoreUma consulta begins_withConsultas recursivas (N+1) ou uma caminhada GSI
PedidosOrdem de caminho, grátisDeve adicionar um atributo de classificação explícito
Mover/renomearReescrever todos os descendentesAtualize um ponteiro pai
Lista de filhos diretosPrecisa de atributo de profundidade ou GSINatural (pai = x)

As chaves compostas vencem quando as leituras são em forma de subárvore e ordenadas; o o modelo flat-ID vence quando a árvore sofre mutações constantes. A maioria das hierarquias de leitura pesada - árvores de arquivos, árvores de categorias, organogramas — composição enxuta.

Armadilhas e próximos passos

  • Não sobrecarregue a chave. Tudo o que você codifica é imutável e indexado por apenas prefixo. Os atributos que você consulta por igualdade pertencem a seus próprios campos ou a um GSI, não preso na chave de classificação.
  • Uma chave de classificação não pode fazer WHERE arbitrário. Somente begins_with, between e comparações. Se você estiver buscando um FilterExpression, você provavelmente modelou a chave errada - consulte Query vs. Scan.
  • Aprofundando-se no design principal reside em design de tabela única; para quando uma subárvore é lida precisa de um índice em vez da tabela base, consulte GSI vs. LSI.

Construa a condição chave begins_with com o Expression Builder, então download DynoTable para executar essas consultas de prefixo nas suas próprias tabelas e observe uma subárvore retornar na ordem do caminho. (E o auto-`JUNTE-SE' a você deixado para trás em SQL? DynoTable's SQL Workbench ainda roda quando você precisar.)

Atualizado

Experimente este design de forma interativa

Esboce suas entidades e padrões de acesso na ferramenta gratuita de Single-Table Design do DynamoDB — ela sugere modelos de chave PK/SK, prevê as coleções de itens e mostra quais padrões precisam de um GSI.

Abrir a ferramenta de Single-Table Design