DevGuideTK
← Trilha Backend

Bancos de documentos

Dados guardados como documentos aninhados, com esquema flexível e as consultas que isso dificulta.

As decisões num banco de documentos são cinco: o que embutir, como lidar com listas grandes, quanto esquema impor, como garantir a consistência e quando um banco de documentos é a escolha certa.

O que embutir

A pergunta que guia a modelagem é como os dados são lidos, e não como se relacionam. Comece pelas telas e pelas consultas mais frequentes.

RelaçãoPadrãoExemplo
Um para poucos, lidos juntosEmbutirEndereços do cliente, itens do pedido
Um para muitos, lidos separadosReferenciar: o filho guarda o identificador do paiPedidos do cliente: cada pedido tem cliente_id
Um para milhõesReferenciar no filho, nunca uma lista no paiEventos de um sensor, acessos de um usuário
Muitos para muitosLista de identificadores num dos lados, ou nos doisAlunos e turmas
Dado compartilhado lido juntoEmbutir uma cópia parcial, e referenciar o originalNome e foto do autor em cada comentário

Padrões que resolvem casos comuns

PadrãoComo funcionaQuando
SubconjuntoEmbute os itens mais usados (os 10 comentários mais recentes) e guarda o resto em outra coleçãoA tela mostra só uma parte da lista
Cópia parcial (extended reference)Embute só os campos do outro documento que a tela usaNome do cliente no pedido
Balde (bucket)Agrupa muitos itens pequenos em documentos por período ou quantidadeMedições de sensores, uma hora por documento
Versão do esquemaUm campo versao_esquema em cada documentoDocumentos de formas diferentes convivendo durante uma migração
Valor calculadoGuarda um total ou uma contagem, atualizado a cada mudançaNúmero de comentários de uma postagem

Listas grandes

No teste do nível Conceito, uma postagem estourou o limite de 16 MB com 15.500 comentários de 1 KB. Bem antes disso, cada leitura da postagem carregava megabytes de comentários.

SaídaComo
Coleção própriaComentários com postagem_id e índice; a postagem guarda só a contagem
SubconjuntoA postagem guarda os 10 últimos; o resto fica na coleção própria
Limite explícito$push com $slice mantém só os N mais recentes, quando o histórico antigo não importa

Quanto esquema impor

NívelComoQuando
NenhumQualquer documento entraProtótipos, e nada mais
Na aplicaçãoTipos e validação no código (Zod, Pydantic, classes)Sempre, como primeira barreira
No banco$jsonSchema na coleçãoCampos obrigatórios, tipos e valores permitidos que nenhuma versão pode violar
No banco, em modo de avisovalidationAction: "warn"Coleções antigas, para descobrir os documentos fora do padrão antes de recusar

A validação no banco pega o que a aplicação deixa passar: uma versão antiga do código ainda rodando, um script de correção, uma importação. No teste, a coleção sem validação devolveu 745 de 894 pedidos numa consulta de faturamento, porque 149 tinham o total em texto. Com o $jsonSchema, esse documento foi recusado na gravação.

A validação não é retroativa: documentos que já estavam na coleção continuam lá. Para encontrá-los, consulte com $jsonSchema no filtro, ou procure tipos com $type.

Como garantir a consistência

OperaçãoComo fazer
Alterar um documento com uma condiçãoCondição no filtro e alteração com operadores ($inc, $set, $push) no mesmo comando
Alterar vários documentos juntosTransação entre documentos (exige conjunto de réplicas)
Cópias de dados compartilhadosAtualizar as cópias com updateMany, numa tarefa em segundo plano, ou aceitar que fiquem como estavam (o preço na compra)
UnicidadeÍndice único, como no relacional

A primeira linha é a mais importante: no teste, ler, conferir e gravar vendeu 30 unidades de um estoque de 10; a atualização condicional vendeu 10.

Documentos, relacional com jsonb, ou os dois

Banco de documentos (MongoDB)PostgreSQL com jsonb
Junções e transações entre várias tabelasPossíveis, mas caras e menos naturaisNaturais
Documentos aninhados e esquema variávelO modelo principalNuma coluna, com índices GIN
Escala horizontal com particionamentoEmbutida (sharding)Extensões e serviços (Citus)
Consultas sobre documentosLinguagem própria e pipelines de agregaçãoSQL com operadores de jsonb
Busca no teste: pedidos com um produto, 100 mil documentos, com índice1 ms0,53 ms

O banco de documentos é a escolha natural quando os dados são de fato documentos, lidos e gravados inteiros, com formas que variam (catálogos com atributos diferentes por categoria, conteúdo, perfis, configurações), e quando a escala horizontal embutida pesa. Quando os dados são relacionais e só uma parte varia, uma coluna jsonb resolve sem um segundo banco.

Resumo da decisão

  1. Modele pelas leituras: embuta o que é lido junto e tem tamanho limitado.
  2. Referencie o que cresce sem limite ou é compartilhado.
  3. Valide o esquema no banco com $jsonSchema, além da aplicação.
  4. Atualizações condicionais atômicas, nunca ler, conferir e gravar.
  5. Índices nos campos aninhados consultados.
  6. Transações entre documentos só como exceção; se forem a regra, o modelo é relacional.

O próximo nível mostra a atualização condicional nas cinco linguagens e a validação de esquema.

Prompts para aprofundar

Ao abrir no ChatGPT ou no Claude, o prompt é enviado ao serviço escolhido pela URL e também fica copiado na sua área de transferência.

  • Modelar meus dados em documentos

    Quero modelar os dados do meu sistema num banco de documentos.
    
    Pergunte o que o sistema faz, quais são as telas e consultas mais frequentes, o volume de cada tipo de dado e quais dados mudam com frequência.
    
    Proponha os documentos, explicando para cada relação se embute ou referencia e por quê, quais padrões de modelagem se aplicam, a validação de esquema de cada coleção e os índices. No final, aponte as partes que ficariam melhores num banco relacional.
  • MongoDB ou PostgreSQL com jsonb

    Estou decidindo entre um banco de documentos e o PostgreSQL com colunas jsonb.
    
    Pergunte como são os meus dados, quanto da estrutura varia, que consultas e relatórios preciso, se há operações que alteram vários registros juntos e qual é a escala esperada.
    
    Compare para o meu caso: modelagem, consistência, consultas, índices, escala horizontal, operação e custo. Recomende uma opção e explique o que eu perderia com a outra.
  • Migrar a forma dos documentos

    Preciso mudar a forma dos documentos de uma coleção que já tem milhões de registros.
    
    Pergunte qual é a mudança, qual banco e linguagem eu uso e como é o deploy.
    
    Compare: migrar tudo de uma vez em lotes, migrar na leitura com um campo de versão do esquema, e manter as duas formas para sempre. Monte comigo o plano escolhido, com o código que lê as duas formas, a validação durante a transição e como saber que terminou.