trilha

System Design/02 - Componentes/Databases2 min

Document Store

Perguntas-guia
  • Que problema isso resolve?
  • Quando usar / quando NÃO usar?
  • Qual o principal trade-off?
  • Como isso falha em produção?

Conceito

Guarda documentos semiestruturados (JSON, BSON) e permite consultar por dentro deles — a diferença essencial em relação a Key-Value Store, onde o valor é opaco.

{ "_id": 42, "nome": "Ana",
  "enderecos": [ { "tipo": "casa", "cidade": "SP" } ],
  "pedidos": [ { "id": 1, "total": 99.9 } ] }

Exemplos: MongoDB, CouchDB, DynamoDB, Firestore, Elasticsearch — e PostgreSQL com jsonb, que cobre boa parte dos casos com transação ACID por cima.

Embutir ou referenciar

A decisão de modelagem central:

Embutir Referenciar
Leitura Uma operação Várias, ou $lookup
Atualização Reescreve o documento Independente
Bom quando Relação 1:poucos, lido junto 1:muitos ilimitado, dado compartilhado
Risco Documento cresce sem limite Volta o custo de junção

A regra prática: embuta o que é sempre lido junto e tem tamanho limitado. Comentários de um post podem ser milhares — referencie. Endereços de um usuário são poucos — embuta.

Trade-offs

Schema flexível é o argumento de venda e a fonte da dívida. Sem validação na escrita, o mesmo campo aparece como "idade": 30, "idade": "30" e ausente — e a aplicação precisa lidar com todas as variações para sempre. Bancos de documento modernos oferecem validação de schema justamente porque essa liberdade se mostrou cara.

O limite de tamanho do documento é real (16 MB no MongoDB) e é atingido por arrays que crescem sem controle — o unbounded array é o antipadrão de modelagem mais comum.

Junções existem ($lookup) e são caras: o modelo não foi feito para elas. Se as consultas cruzam coleções o tempo todo, o modelo relacional provavelmente era o certo.

E vale repetir: Postgres com jsonb dá flexibilidade de documento, índices GIN sobre o JSON, e transação ACID multi-tabela. "Preciso de schema flexível" não implica necessariamente trocar de banco.

Exemplo prático

Um catálogo de produtos em que cada categoria tem atributos diferentes — camiseta tem tamanho e cor, notebook tem processador e memória.

No modelo relacional, isso vira uma tabela de atributos genéricos (EAV) com consultas desconfortáveis, ou uma tabela por categoria. No modelo de documento, cada produto simplesmente carrega seus campos.

O produto inteiro é lido numa operação, com variantes e imagens embutidas. A consulta por atributo ({"cor": "azul"}) funciona com um índice.

O limite aparece quando surge a pergunta "quantos produtos foram vendidos por categoria no último trimestre" — agregação analítica cruzando coleções. Aí o caminho é replicar para um banco analítico, não forçar o documento.

Relacionado


Parte de Databases · roadmap.sh/system-design

Buscar

Busca por título, seção e texto das notas