Intermediário7 min de leitura

Quando NÃO Usar Single-Table Design no DynamoDB

Single-table design é o conselho padrão para DynamoDB, e ele merece: um Query devolve um pai e seus filhos, sem joins, sem N+1.

Mas é uma troca — você compra velocidade de leitura com um schema rígido e opaco. Algumas cargas de trabalho não podem pagar esse preço, e forçar uma tabela nelas é sua própria cilada.

Quando não usar single-table design no DynamoDB?

Evite single-table design quando sua carga de trabalho for de analytics OLAP pesado, CRUD simples com poucas entidades não relacionadas, ou entidades que escalam e falham de forma independente. Nesses casos, múltiplas tabelas leem melhor, custam o mesmo e ficam mais flexíveis. Single-table design só vence quando os padrões de acesso são conhecidos, relacionados e de alto volume.

  • Analytics pesado? Não use single-table. Chaves sobrecarregadas são hostis ao OLAP — exporte para um armazenamento colunar e consulte lá.
  • CRUD simples com um punhado de padrões de acesso? Uma tabela por entidade está ótimo, legível, e não te custa nada em performance.
  • Entidades que escalam ou falham independentemente? Tabelas separadas te deixam ajustar, cobrar e isolar o raio de explosão de cada uma por conta própria.
  • Single-table ainda vence quando seus padrões são conhecidos, relacionados e de alto volume — esse é o caso para o qual foi feito.

Saiba o que single-table de fato custa

Single-table design não é grátis; ele só move o custo para fora do caminho de leitura e para todo o resto. Você paga em legibilidade e flexibilidade.

Uma tabela contendo cinco tipos de entidade por trás de PK/SK é difícil de ler, difícil de fazer onboarding e difícil de mudar. Um novo padrão de acesso pode significar um backfill em todo tipo de item da partição.

Então a pergunta não é "single-table é bom?". É "meus padrões de acesso justificam a rigidez?". Quando não justificam, recorra a múltiplas tabelas.

Não faça single-table de uma carga de analytics

O DynamoDB é feito para OLTP — leituras pequenas, conhecidas, point-and-range. Analytics é OLAP: GROUP BY, grandes agregações, fatiamento ad-hoc em todo o dataset. Os dois puxam em direções opostas.

Single-table design piora o OLAP, não melhora. Chaves sobrecarregadas e tipos de entidade misturados significam que um job de analytics precisa primeiro desembaraçar qual item é qual antes de poder somar qualquer coisa — o oposto de um scan colunar limpo.

Vindo do SQL, o reflexo é escrever a agregação contra a tabela ativa. No DynamoDB isso é um Scan completo — você paga por e lê todo item, que é a cilada do Scan em volume total.

A correção não é uma chave mais esperta. É um armazenamento diferente. A própria orientação da AWS é exportar o DynamoDB para o S3 e rodar analytics com um engine de consulta como o Athena.

Mantenha OLTP e OLAP em engines separados (AWS DynamoDB Developer Guide, S3DataExport.html).

Não faça single-table de CRUD simples

Se o seu app lê e escreve algumas entidades não relacionadas pelo próprio id, e você tem talvez três padrões de acesso, single-table não te compra nada.

Pegue uma tabela Tenants e uma tabela ApiKeys para uma pequena ferramenta B2B:

Tenants
TenantIdNamePlanTier
TNT-8842Northwindpro
ApiKeys
KeyIdTenantIdScope
KEY-01H9...TNT-8842read-write

Cada consulta é um GetItem por id, ou um Query em um GSI chaveado por TenantId. Não há busca de pai-e-filhos para otimizar, então não há nada para uma partição sobrecarregada ganhar. Duas tabelas claras leem melhor do que uma turva.

A cilada é fazer cargo cult de single-table porque é "boa prática". A boa prática é padrão-de-acesso-primeiro. Se os padrões são triviais, a forma simples é a forma certa.

Separe tabelas que escalam ou falham independentemente

Uma única tabela compartilha uma superfície de throughput, um backup, um raio de explosão. Quando duas entidades têm taxas de escrita ou necessidades de durabilidade muito diferentes, esse destino compartilhado vira uma desvantagem.

Imagine um sistema de rastreamento de frota. Veículos mudam raramente; sua telemetria despeja a cada segundo:

Vehicles (frio, baixa taxa de escrita)
VehicleIdMakeModelRegion
VEH-204VolvoFH16eu-west
Telemetry (quente, alta taxa de escrita, com TTL)
DeviceTsVehicleIdSpeedKphFuel
2026-06-23T10:00:01ZVEH-204880.61

Duas tabelas te deixam provisionar a telemetria para uma mangueira de incêndio, manter os veículos minúsculos e baratos, definir um TTL só na telemetria, e impedir que uma tempestade de escrita de telemetria cause throttling nas leituras do catálogo de veículos. Uma tabela acopla tudo isso.

Conforme o paper Amazon Dynamo de 2007, particionamento e disponibilidade são preocupações de primeira classe — tabelas independentes te dão controle independente sobre ambos.

Mapeie a decisão antes de comprometer

Passe a carga por um único portão: as entidades são relacionadas, e os padrões são conhecidos e de alto volume? Se não, múltiplas tabelas.

Eis a decisão como um fluxo — comece no topo e siga o primeiro ramo que corresponder:

SimNãoNãoSimNãoSimNova cargaAnalytics pesadoou OLAP?Armazenamento separado(export + Athena)Entidades relacionadas+ buscadas juntas?Múltiplas tabelas(CRUD simples)Padrões conhecidos,de altovolume?Múltiplas tabelas(mantenha flexível)Single-tabledesign

Só a folha do canto inferior direito merece single-table; todo outro caminho é melhor servido por mais de uma tabela.

Single vs múltiplas, frente a frente

FatorSingle-tableMúltiplas tabelas
Leituras relacionadasUm Query, sem joinsJoin no cliente ou idas e voltas extras
LegibilidadeChaves sobrecarregadas opacasUma entidade por tabela, autodocumentada
Novo padrão de acessoMuitas vezes um backfillAdicione uma tabela ou GSI isoladamente
Analytics / OLAPHostil — desembaraçar antes de agregarAinda exporta, mas mais limpo por entidade
Escalonamento independenteThroughput + raio de explosão compartilhadosAjuste, cobre, TTL e backup separadamente
Melhor quandoPadrões conhecidos, relacionados, de alto volumeNão relacionados, em evolução ou analíticos

Ciladas + próximos passos

O erro espelhado é supercorrigir — dividir entidades genuinamente relacionadas e de alto volume em uma tabela por entidade e reconstruir joins estilo SQL no seu app. Essa é a cilada do N+1 que o single-table mata.

Escolha a forma que os padrões de acesso pedem, não o dogma.

Quando você for modelar relacionamentos, apoie-se no tipo de índice certo — veja GSI vs LSI antes de adicionar um.

Quando você for escrever uma consulta contra um schema multi-tabela, esboce a KeyConditionExpression no DynamoDB Expression Builder primeiro.

Assim você pega uma forma de Scan completo antes que ela chegue à produção.

Depois experimente o DynoTable para navegar em ambas as formas contra suas próprias tabelas e ver qual delas seus padrões de acesso realmente querem.

Atualizado