MongoDB vs PostgreSQL: Escolhendo o Banco Certo para seu Projeto
A Pergunta Errada e a Pergunta Certa
A pergunta “MongoDB ou PostgreSQL?” geralmente é a errada. A pergunta certa é: “qual modelo de dados faz mais sentido para o meu problema?”
Em 2026, o PostgreSQL suporta JSON nativo com performance excelente, e o MongoDB ganhou suporte a transações ACID. A escolha é menos binária do que parece.
Quando PostgreSQL é a Escolha Óbvia
- Dados com relacionamentos claros e estáveis (usuários, pedidos, produtos)
- Necessidade de JOINs complexos e transações ACID entre múltiplas entidades
- Queries analíticas e relatórios
- Time tem experiência com SQL
- Compliance e auditoria (WAL, point-in-time recovery)
-- PostgreSQL brilha em queries relacionais
SELECT
u.nome,
COUNT(p.id) AS total_pedidos,
SUM(p.valor) AS receita_total,
AVG(p.valor) AS ticket_medio
FROM usuarios u
JOIN pedidos p ON p.usuario_id = u.id
JOIN itens_pedido ip ON ip.pedido_id = p.id
WHERE p.status = 'concluido'
AND p.criado_em >= NOW() - INTERVAL '90 days'
GROUP BY u.id, u.nome
HAVING COUNT(p.id) >= 3
ORDER BY receita_total DESC
LIMIT 100;Quando MongoDB Faz Sentido
- Schema evolui rapidamente (protótipos, startups early-stage)
- Documentos semi-estruturados sem relacionamentos (logs, eventos, configurações)
- Dados que naturalmente vivem juntos (post + comentários + reações)
- Sharding horizontal desde o início para escala massiva
// MongoDB brilha em documentos auto-contidos
db.artigos.insertOne({
titulo: "MongoDB vs PostgreSQL",
autor: { nome: "Paulo", avatar: "/img/paulo.jpg" },
conteudo: "...",
tags: ["banco", "mongodb", "postgresql"],
comentarios: [
{ usuario: "Ana", texto: "Ótimo artigo!", data: new Date() },
{ usuario: "Bruno", texto: "Muito útil", data: new Date() }
],
metricas: { views: 1250, likes: 87 }
});JSON no PostgreSQL: O Melhor dos Dois Mundos?
-- PostgreSQL suporta JSONB com índices GIN
CREATE TABLE eventos (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
tipo TEXT NOT NULL,
payload JSONB NOT NULL,
criado_em TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX idx_eventos_payload ON eventos USING GIN(payload);
-- Query em campos JSON
SELECT * FROM eventos
WHERE payload @> '{"usuario_id": 123}'
AND payload->>'status' = 'ativo'
AND (payload->>'valor')::numeric > 100;
-- Agrega campos JSON
SELECT
tipo,
AVG((payload->>'valor')::numeric) AS media_valor,
COUNT(*) AS total
FROM eventos
GROUP BY tipo;Isso elimina um dos principais argumentos a favor do MongoDB para dados flexíveis.
Performance: Mitos vs Realidade
Mito: “MongoDB é mais rápido que PostgreSQL” Realidade: Depende completamente do padrão de acesso.
// MongoDB é rápido para:
// Buscar um documento por _id (sem JOINs)
db.usuarios.findOne({ _id: ObjectId("...") })
// Inserção de alto throughput (writes desnormalizados)
db.eventos.insertMany([...milhares de eventos...])-- PostgreSQL é rápido para:
-- Queries com índices B-tree
SELECT * FROM usuarios WHERE email = 'paulo@exemplo.com';
-- Agregações em colunas indexadas
SELECT status, COUNT(*) FROM pedidos GROUP BY status;Benchmark honesto: para uma API CRUD simples com índices adequados, a diferença é menor que 20% — irrelevante na maioria dos casos.
Transações: O Maior Diferencial Histórico
# PostgreSQL: transações ACID multi-tabela nativas desde sempre
with db.transaction():
conta_origem.saldo -= valor
conta_destino.saldo += valor
historico.registrar(transacao)
# Ou tudo, ou nada — desde 1995
# MongoDB: transações multi-documento desde 4.0 (2018)
with client.start_session() as session:
with session.start_transaction():
db.contas.update_one({"_id": origem_id}, {"$inc": {"saldo": -valor}}, session=session)
db.contas.update_one({"_id": destino_id}, {"$inc": {"saldo": valor}}, session=session)
# Funciona, mas tem overhead maiorSchema Migrations
# PostgreSQL: migrations explícitas (Alembic, Flyway)
# Chato, mas seguro — o schema é a verdade
# MongoDB: schema livre por padrão
# Fácil no início, doloroso depois
# Use Mongoose/Motor com validação de schema:
from motor.motor_asyncio import AsyncIOMotorClient
schema_usuario = {
"bsonType": "object",
"required": ["nome", "email"],
"properties": {
"nome": {"bsonType": "string"},
"email": {"bsonType": "string"},
"idade": {"bsonType": "int", "minimum": 0}
}
}
await db.command("collMod", "usuarios", validator={"$jsonSchema": schema_usuario})Guia de Decisão Rápida
| Critério | PostgreSQL | MongoDB |
|---|---|---|
| Schema fixo e relacional | ✅ Ideal | ⚠️ Possível |
| Documentos auto-contidos | ⚠️ Possível (JSONB) | ✅ Ideal |
| JOINs complexos | ✅ Nativo | ❌ Evitar |
| Transações ACID críticas | ✅ Nativo | ⚠️ Com overhead |
| Sharding horizontal | ⚠️ Citus/extensões | ✅ Nativo |
| Dados de log/eventos | ⚠️ BRIN index | ✅ Ideal |
| Time conhece SQL | ✅ | ❌ Curva de aprendizado |
| Flexibilidade de schema | ⚠️ JSONB ajuda | ✅ Ideal |
Conclusão
Para a maioria dos projetos web em 2026, PostgreSQL com JSONB é a escolha mais segura — você ganha ACID, SQL poderoso e flexibilidade para dados semi-estruturados. MongoDB vale a pena quando você está construindo algo que naturalmente é um sistema de documentos em escala massiva, ou quando a equipe já tem expertise nele.
Quando em dúvida, comece com PostgreSQL.