Intermediário7 min de leitura

O Atributo Type no DynamoDB

No SQL, a tabela de uma linha é o seu tipo — uma linha em documents é um documento. Uma tabela única no DynamoDB mistura todas as entidades sob um mesmo schema, então um item não carrega resposta nenhuma embutida para "o que é isto?".

O atributo Type devolve essa resposta: uma string simples em cada item nomeando a entidade que ele representa.

O que é o atributo Type no DynamoDB?

O atributo Type é uma string simples que você carimba em cada item — como EntityType: "Document" — nomeando a entidade que aquele item representa. Como uma tabela única mistura muitas entidades sob um mesmo schema, os itens não carregam tipo nenhum embutido. O Type devolve essa informação, para que seu código identifique registros, filtre uma GSI para uma única entidade e sobreviva a migrações.

  • Carimbe um Type em toda escrita. Um atributo — EntityType: "Document" — em cada item, sem exceções. Custa alguns bytes e te salva depois.
  • Ele identifica entidades em uma partição mista. Um Query retorna workspaces, documentos e comentários juntos; o Type diz ao seu código qual é qual sem analisar prefixos de chave.
  • Ele viabiliza a filtragem de uma única entidade em uma GSI. Projete o Type em um índice e você consegue restringir um índice sobrecarregado a exatamente um tipo de entidade.
  • Ele é sua saída de emergência para migrações. Quando você exporta para remodelar ou move uma entidade para a própria tabela, o Type é a coluna pela qual você divide.

Por que uma tabela mista perde o tipo

O single-table design guarda toda entidade em uma única tabela atrás de chaves genéricas como PK e SK. Esse é justamente o ponto — um Query retorna um pai e seus filhos juntos. Mas isso significa que uma partição é heterogênea.

Pegue um app SaaS de colaboração em documentos. Uma partição de workspace guarda o registro do workspace, seus documentos e os comentários nesses documentos:

PKSKattributes
WS#acmeMETAname, plan, seats
WS#acmeDOC#a1#METAtitle, owner, wordCount
WS#acmeDOC#a1#CMT#0007author, body, createdAt
WS#acmeDOC#a1#CMT#0008author, body, createdAt

Query PK = "WS#acme" devolve os quatro itens em uma única leitura cobrada. Agora seu código tem uma lista de itens crus e nenhuma forma confiável de dizer qual é um documento e qual é um comentário — a não ser fazendo string-matching no SK, o que é frágil no instante em que seu formato de chave muda.

Carimbe o Type em cada item

A correção é um atributo em toda escrita, nomeando a entidade:

PKSKEntityTypetitle
WS#acmeMETAWorkspace
WS#acmeDOC#a1#METADocumentQ3 Roadmap
WS#acmeDOC#a1#CMT#0007Comment

Ramificar com item.EntityType === "Document" é uma checagem de igualdade estável. Analisar SK.startsWith("DOC#") && SK.includes("#CMT#") é um palpite que quebra quando você muda a versão da chave. O Type desacopla sua lógica de leitura da sua codificação de chave — esse é o ganho de verdade.

Query PK = 'WS#acme'Partição mistaEntityType: 'Workspace'EntityType: 'Document'EntityType: 'Comment'Rotear por Type

Uma leitura retorna três tipos de entidade; o atributo Type roteia cada item para o handler certo sem tocar nas chaves.

Filtre uma GSI para uma única entidade

O Type ganha o seu sustento nos índices. Digamos que você adicione uma GSI com chave GSI1PK = WS#acme, GSI1SK = updatedAt para listar "tudo que mudou recentemente neste workspace, do mais novo ao mais antigo". Um índice sobrecarregado arrasta documentos e comentários — mas uma UI de feed pode querer apenas documentos.

Duas formas de restringir, e a diferença é dinheiro:

AbordagemQuanto custaQuando usar
FilterExpression no TypeLê todos os itens correspondentes, cobra por todos eles, descarta os não-match após a leituraEntidades misturadas são raras no resultado; rápido de entregar
Índice esparso (Type no GSI1PK)Só a entidade que você quer chega ao índiceUma entidade domina; você quer zero desperdício

Um FilterExpression roda depois que os itens são lidos e depois que a capacidade é consumida — a AWS é explícita de que filtrar não reduz o custo de leitura (DynamoDB Developer Guide: FilterExpression). Filtrar pelo Type é honesto, não grátis: você paga pelos comentários que joga fora.

Para restringir o feed a documentos, a query carrega uma condição no atributo Type. Monte o FilterExpression, os nomes e os valores com o DynamoDB expression builder — ele emite o placeholder #t = :doc para você não digitar errado uma palavra reservada.

KeyConditionExpression     GSI1PK = :ws
FilterExpression           #t = :doc
ExpressionAttributeNames   { "#t": "EntityType" }
ExpressionAttributeValues  { ":ws": "WS#acme", ":doc": "Document" }

Quer que o índice carregue apenas documentos e pule o filtro por completo? Escreva GSI1PK somente nos itens de documento — um índice esparso. Itens sem a chave da GSI nunca replicam para o índice, então a leitura toca apenas documentos. O atributo Type é o que diz ao seu escritor quais itens se qualificam.

Mantenha o valor estável e singular

Escolha o valor uma vez e trate-o como um enum. Document, nunca às vezes Doc e às vezes document — um valor que oscila é pior do que valor nenhum, porque suas checagens de igualdade passam em uma capitalização e silenciosamente erram a outra.

Um Type por item. Se um item parece ser duas entidades, isso normalmente é um cheiro de modelagem — deveriam ser dois itens, cada um na própria coleção ou faixa de sort key, não uma linha vestindo dois chapéus.

O retorno da migração

A razão para carimbar o Type antes de precisar dele: a remodelagem. O caminho de remodelagem recomendado é exportar, transformar, reimportar — e a AWS documenta a exportação em massa para o S3 exatamente para esse tipo de reshaping offline (Exportando DynamoDB para S3).

Quando esse dia chegar, o Type é a coluna pela qual você faz GROUP BY. Quer elevar comentários para a própria tabela, ou renormalizar a exportação em arquivos por entidade para um data warehouse de analytics? Você divide o dump pelo EntityType. Sem ele, você volta a fazer engenharia reversa de chaves em milhões de linhas.

Próximos passos

O atributo Type é seguro barato: identifica entidades em uma leitura mista, filtra uma GSI sobrecarregada e divide de forma limpa quando você remodela. Carimbe-o em toda escrita desde o primeiro dia — retrofitá-lo em uma tabela viva significa um backfill completo.

Leitura relacionada: single-table design para o padrão de partição mista que isto serve, GSI vs LSI para escolher o formato de índice por trás de um índice esparso, e Query vs Scan para entender por que um FilterExpression nunca te economiza custo de leitura.

Monte o filtro no Type com o DynamoDB expression builder e experimente o DynoTable para navegar por uma tabela real de entidades mistas e ver a coluna Type se alinhar em cada item.

Atualizado