Tecnologias/05 - Comparações6 min
MongoDB vs Relacional
Conceito
A comparação de 2013 era "SQL vs NoSQL" e virou guerra de religião. Em 2026 os dois lados convergiram tanto que a pergunta mudou de forma:
- O MongoDB ganhou transação ACID multi-documento, validação de schema,
$lookupe SQL-like via Atlas. - O PostgreSQL ganhou
jsonbcom índice GIN — um banco de documentos competente dentro de um relacional.
Então a pergunta útil não é mais "qual é melhor". É:
O meu acesso a dados é sempre por uma raiz conhecida, ou eu preciso cruzar dados de formas que ainda não sei?
Se é sempre por raiz (o pedido, o perfil, o dispositivo, o carrinho), documento é uma
representação honesta. Se você precisa cruzar, agrupar e responder perguntas novas,
relacional é a escolha — e você vai precisar de JOIN de verdade.
Lado a lado
| MongoDB | Relacional (Postgres/MySQL/Oracle) | |
|---|---|---|
| Unidade de dado | documento (agregado) | linha normalizada |
| Schema | na aplicação (validação opcional) | no banco, obrigatório |
| Modelagem | pelas consultas | pelas entidades |
| Junção | $lookup (sem otimizador de join) |
JOIN nativo e otimizado |
| Integridade referencial | não existe | FK, cascade, constraint |
| Transação | multi-documento desde 4.0, com custo | o caso normal |
| Atomicidade grátis | por documento | por linha |
| Consulta ad-hoc | limitada ao previsto | excelente |
| Agregação analítica | pipeline (bom, verboso) | SQL + window functions |
| Escala de leitura | réplicas | réplicas |
| Escala de escrita | sharding nativo | vertical → Sharding manual |
| Evolução de schema | escrever no formato novo | ALTER TABLE (+ migração) |
| Consistência | configurável por operação | forte por padrão |
| Ferramental de BI | exportar / Atlas Federation | nativo, universal |
Onde cada um ganha, concretamente
MongoDB é a escolha melhor quando:
- O agregado é a unidade natural de leitura e de escrita — carrinho, sessão, perfil, documento de conteúdo (CMS), configuração de tenant.
- O schema varia por registro de forma legítima: catálogo de produtos onde cada categoria tem atributos próprios (uma TV tem polegadas, um livro tem ISBN). Em SQL isso é EAV ou 40 colunas nulas — os dois ruins.
- O volume de escrita precisa passar de um nó, com padrão de acesso conhecido. Sharding é nativo aqui e é projeto no relacional.
- Séries temporais e ingestão de eventos (com bucket pattern ou time series collections).
- O produto está em descoberta e o schema muda toda semana.
Relacional é a escolha melhor quando:
- Há muitos-para-muitos de verdade e o dado é lido por caminhos diferentes.
- Integridade referencial importa: financeiro, estoque, cadastro regulado.
- Uma operação toca 4 entidades e precisa ser atômica como regra, não exceção.
- Relatório e BI são requisito — quem consome é o time de dados, com SQL.
- As perguntas ao dado vão mudar e você não pode remodelar a cada uma.
"Não sei ainda como será o modelo, então uso Mongo porque é flexível." Se você não sabe as consultas, você não pode modelar o documento — e schema flexível é exatamente o oposto do que ajuda aí. Sem consultas definidas, o relacional normalizado é a aposta mais segura: dá para fazer qualquer pergunta depois.
E o jsonb do Postgres?
É a comparação honesta de 2026, e a resposta é matizada:
Postgres jsonb |
MongoDB | |
|---|---|---|
| Documento aninhado com índice | sim (GIN) | sim |
| Atualização parcial de campo profundo | jsonb_set (reescreve o valor) |
$set em caminho, mais natural |
| Misturar relacional + documento na mesma query | sim, e é o grande argumento | não se aplica |
| Sharding de escrita | não nativo | nativo |
| Ergonomia de driver e agregação | SQL + funções JSON | pipeline nativo |
| Transação sobre vários documentos | trivial | possível, com custo |
Regra prática: se o documento é uma parte do sistema, jsonb no Postgres. Se o
documento é o sistema, e a escrita precisa escalar horizontalmente, MongoDB.
Trade-offs
Usar um como o outro é o pior resultado possível. MongoDB normalizado com $lookup
por toda parte tem as desvantagens dos dois: sem JOIN otimizado, sem FK, sem transação
por padrão — e ainda paga a complexidade. Postgres usado como key-value com uma coluna
jsonb gigante desperdiça tudo o que ele oferece.
O custo de trocar é assimétrico. Sair de relacional para documento é uma remodelagem (dá trabalho, é factível). Sair de documento para relacional exige descobrir o schema que nunca foi declarado a partir de dados reais e inconsistentes. Comece pelo mais restritivo se estiver em dúvida: é mais fácil relaxar depois.
Poliglota é uma resposta legítima, com um custo real. Postgres como fonte da verdade transacional + MongoDB para catálogo/conteúdo é um desenho comum e sensato. O preço é sincronização — que é onde entra Kafka com change streams / CDC, e onde a consistência passa a ser eventual por construção (Eventual Consistency).
O trade-off central: relacional protege você do futuro (qualquer pergunta ainda é possível). Documento otimiza para o presente (a consulta que você tem é rápida e simples). Escolha pelo grau de certeza que você tem sobre as suas consultas — não pela moda nem pela linguagem do driver.
Exemplo prático
Um catálogo de e-commerce, o caso onde a comparação fica nítida:
-- Relacional: atributos variáveis por categoria → EAV, e ninguém gosta de EAV
CREATE TABLE produtos (id bigint PRIMARY KEY, nome text, preco numeric, categoria_id int);
CREATE TABLE atributos (produto_id bigint, chave text, valor text); -- consulta virou pivot
SELECT p.nome
FROM produtos p
JOIN atributos a1 ON a1.produto_id = p.id AND a1.chave='polegadas' AND a1.valor='55'
JOIN atributos a2 ON a2.produto_id = p.id AND a2.chave='resolucao' AND a2.valor='4K';
-- um JOIN por filtro. Com 5 filtros, 5 joins.
// MongoDB: cada produto carrega os próprios atributos
{ _id: 1, nome: "TV X", preco: 2999, categoria: "tv",
attrs: { polegadas: 55, resolucao: "4K", hdr: true } }
db.produtos.createIndex({ categoria: 1, "attrs.polegadas": 1, "attrs.resolucao": 1 })
db.produtos.find({ categoria: "tv", "attrs.polegadas": 55, "attrs.resolucao": "4K" })
// um filtro, um índice, zero join
-- ✅ E a terceira via, que na prática vence muitos projetos:
CREATE TABLE produtos (
id bigint PRIMARY KEY,
nome text NOT NULL, preco numeric(12,2) NOT NULL, -- relacional onde importa
categoria_id int REFERENCES categorias(id), -- FK de verdade
attrs jsonb NOT NULL DEFAULT '{}' -- documento onde varia
);
CREATE INDEX ON produtos USING GIN (attrs);
SELECT nome FROM produtos
WHERE categoria_id = 7 AND attrs @> '{"polegadas": 55, "resolucao": "4K"}';
A terceira via junta preço com constraint, FK com integridade e atributos flexíveis indexados — na mesma transação e na mesma query. Não é a resposta para todo caso (sharding de escrita não vem incluso), mas é o motivo pelo qual muita equipe que consideraria MongoDB em 2015 fica no Postgres em 2026.
Aprofundamento aplicado
Comparar o custo de mudar uma informação compartilhada
Um catálogo usa o nome do fabricante em milhares de produtos. No desenho normalizado, um registro pode ser a referência corrente. No desenho com cópias, a atualização exige propagar mudanças e decidir o que leitores observam durante essa propagação.
Uma cópia pode ser a escolha correta para leitura frequente ou para preservar história. A pergunta é qual significado ela possui: “nome atual” ou “nome na data da compra”. Os dois modelos conseguem expressar relações e projeções; seus mecanismos e custos diferem.
| Mudança de requisito | Investigar |
|---|---|
| Novo relatório cruzando entidades | Joins, agregações, índices e projeções |
| Crescimento de array embutido | Limites, paginação e divisão do documento |
| Regra sobre várias entidades | Transação, restrições e conflitos |
| Mudança de campo duplicado | Propagação, versionamento e atraso permitido |
Exercício: modele pedido, itens e fabricante das duas formas. Resultado esperado: compare operações de leitura e atualização com regras explícitas, sem concluir que schema flexível elimina contratos ou que normalizar torna toda consulta barata.
Referência: modelagem no MongoDB.
Relacionado
- 1. MongoDB
- 2. Modelagem de Documentos
- SQL vs NoSQL
- Document Store
- 1. PostgreSQL vs MySQL vs Oracle
- Denormalization
- DynamoDB
Parte de MOC Comparações · mongodb.com/docs · postgresql.org/docs/current/datatype-json