Como Escolher o Banco de Dados Correcto para a sua Aplicação em 2026

Duarte Spínola  |  2026-07-13

Escolher o banco de dados por popularidade ou por ser o que já se conhece é o erro mais comum em arquitectura de software. A decisão correcta depende de três factores: o tipo de dados (estruturado, semi-estruturado, não-estruturado), os requisitos de consistência (forte, eventual, quorum) e o padrão de acesso (leitura intensiva, escrita intensiva, transaccional, analítico). O teorema CAP estabelece que em presença de uma partição de rede, é preciso escolher entre consistência e disponibilidade — não é possível ter ambas. Este guia apresenta os critérios técnicos para decidir entre PostgreSQL, MongoDB, Cassandra, DynamoDB, CockroachDB, Redis e SQLite, com cenários reais e uma checklist de decisão. Referência: Teorema CAP — Wikipedia.

Não existe “melhor banco de dados”. Existe o banco de dados correcto para um cenário específico. Uma aplicação financeira precisa de consistência forte (PostgreSQL, CockroachDB). Uma timeline de rede social precisa de disponibilidade e escrita rápida (Cassandra, DynamoDB). Um cache precisa de baixa latência (Redis). A escolha errada causa problemas que nenhuma optimização resolve.

1. Os Três Factores de Decisão

Antes de escolher um banco de dados, responder a três perguntas:

Pergunta Resposta determina Exemplos
Que tipo de dados vou armazenar? SQL vs NoSQL Estruturado (tabelas, relações) → SQL. Semi-estruturado (JSON, documentos) → Documental. Chave-valor simples → Key-value.
Que nível de consistência preciso? CP vs AP no teorema CAP Transacções financeiras → consistência forte. Feed de rede social → consistência eventual.
Que padrão de acesso vou ter? Tipo de banco (relacional, colunar, chave-valor, documento, gráfico) OLTP transaccional → SQL. Escritas massivas distribuídas → Cassandra. Cache de baixa latência → Redis.

Tabela de tipos de banco de dados

Tipo Exemplos Quando usar Quando não usar
Relacional (SQL) PostgreSQL, MySQL, SQLite Dados estruturados, relações, transacções ACID, consistência forte Dados schemaless, escritas massivas distribuídas
Documento (NoSQL) MongoDB, Couchbase Dados semi-estruturados (JSON), schema flexível, leitura por ID Relações complexas, joins multi-nível, transacções multi-documento
Colunar (NoSQL) Cassandra, HBase, ClickHouse Escritas massivas, leitura por coluna, dados temporais, distribuído Transacções ACID, dados relacionais, queries ad-hoc complexas
Chave-Valor (NoSQL) Redis, DynamoDB, Memcached Cache, sessões, contadores, baixa latência (< 1ms) Queries complexas, relações, agregações
NewSQL CockroachDB, TiDB, YugabyteDB Consistência forte + escala horizontal (combina SQL com distribuição) Custo elevado, complexidade operacional
Gráfico Neo4j, Amazon Neptune Relações complexas, recomendações, fraud detection Dados tabulares simples, armazenamento geral
Time-series InfluxDB, TimescaleDB Métricas, IoT, monitorização, dados temporais Dados não-temporais, transacções OLTP
Search Elasticsearch, Meilisearch Busca full-text, analytics, logs Armazenamento primário de dados transacionais

2. Teorema CAP: Consistência, Disponibilidade, Partição

O teorema CAP (Brewer, 2000) estabelece que um sistema distribuído pode garantir no máximo duas de três propriedades:

  • Consistência (Consistency) — todas as leituras recebem a escrita mais recente ou um erro
  • Disponibilidade (Availability) — todo o pedido recebe uma resposta (não necessariamente a mais recente)
  • Tolerância a Partição (Partition tolerance) — o sistema continua a funcionar apesar de falhas de rede entre nós

Como partições de rede são inevitáveis em sistemas distribuídos, a escolha real é entre:

Escolha Tipo Bancos de dados Priorizam
CP Consistência + Partição PostgreSQL (single-node), CockroachDB, MongoDB (configurable) Consistência — recusa pedidos se não puder sincronizar
AP Disponibilidade + Partição Cassandra, DynamoDB, Couchbase Disponibilidade — responde mesmo com dados potencialmente desactualizados
CA Consistência + Disponibilidade PostgreSQL (single-node), SQLite Funciona apenas sem partições — não é distribuído

Em sistemas distribuídos reais, a partição é inevitável. A escolha é sempre entre CP e AP. Bancos CP bloqueiam escritas durante partição para garantir consistência. Bancos AP continuam a aceitar escritas mas podem ter dados inconsistentes temporariamente. Referência: CAP Theorem — Wikipedia.

PACELC: extensão do teorema CAP

O teorema PACELC estende o CAP adicionando latência vs consistência quando não há partição:

  • PA/EL — prioriza disponibilidade e latência (Cassandra, DynamoDB)
  • PC/EC — prioriza consistência e consistência (CockroachDB, Spanner)
  • PA/EC — disponibilidade em partição, consistência sem partição (MongoDB com majority)
  • PC/EL — consistência em partição, latência sem partição (PNUTS)

3. ACID vs BASE

Propriedade ACID BASE
Atomicidade Tudo ou nada Transacções parciais aceites
Consistência Estado sempre válido Consistência eventual
Isolamento Transacções não interferem Leitura eventualmente consistente
Durabilidade Escrita persiste após commit Escrita pode ser perdida em falha
Basically Available Sistema sempre disponível
Soft state Estado pode mudar sem input
Eventually consistent Converge para consistência com tempo
Bancos Modelo
PostgreSQL, MySQL (InnoDB), SQLite, CockroachDB ACID
Cassandra, DynamoDB, Riak BASE (configurable para ACID em casos específicos)
MongoDB Configurable — ACID em transacções multi-documento (4.0+), BASE por defeito

4. PostgreSQL — O Relacional Robusto

O PostgreSQL é o banco relacional open-source mais avançado, com suporte ACID completo, JSON/JSONB, extensões (PostGIS, TimescaleDB, pgvector) e replicação síncrona.

Quando escolher PostgreSQL

Cenário Porquê
Aplicação financeira ACID, transacções, consistência forte
SaaS multi-tenant Esquemas relacionais, row-level security
Aplicação com dados estruturados e semi-estruturados JSONB para dados flexíveis + SQL para queries
Sistema com queries complexas Optimizer maduro, CTE, window functions, índices avançados
Aplicação que precisa de extensibilidade PostGIS, pgvector (IA), TimescaleDB (time-series)

Quando NÃO escolher PostgreSQL

  • Escrita massiva distribuída (>100k writes/sec) — considerar Cassandra
  • Cache de baixa latência — usar Redis como camada à frente
  • Dados schemaless puros sem relações — MongoDB pode ser mais simples
  • Escala horizontal de writes sem complexidade — CockroachDB ou Cassandra

Configuração básica de replicação síncrona (consistência forte)

# postgresql.conf no primary
wal_level = replica
synchronous_commit = on
synchronous_standby_names = ‘replica1’

# Configuração de replicação síncrona — garante que a escrita
# só é confirmada após ser replicada para a réplica
# Isto dá consistência forte mas reduz throughput de escrita

Referência: PostgreSQL — documentação oficial.

5. MongoDB — O Documental Flexível

O MongoDB armazena dados em documentos BSON (binary JSON), sem schema rígido. Suporta transacções multi-documento ACID desde a versão 4.0, mas o seu modelo BASE continua a ser o padrão.

Quando escolher MongoDB

Cenário Porquê
Catálogo de produtos (e-commerce) Schema flexível — cada produto tem atributos diferentes
CMS / gestão de conteúdo Documentos com estrutura variável
Aplicação com iteracção rápida Sem migrations de schema — adicionar campos é automático
Dados semi-estruturados com leitura por ID Indexação por _id é muito rápida

Quando NÃO escolher MongoDB

  • Transacções financeiras multi-documento — PostgreSQL é mais adequado
  • Relações complexas com joins frequentes — SQL é mais expressivo
  • Dados estritamente relacionais — o “schemaless” pode causar inconsistências
  • Consistência forte obrigatória em todas as operações

Configuração de consistência ajustável

// MongoDB — nível de consistência por operação
// Consistência forte (CP) — lê sempre a cópia mais recente
db.collection.find().readConcern(“majority”)

// Consistência eventual (AP) — lê qualquer réplica
db.collection.find().readConcern(“local”)

// Write concern — quantas réplicas devem confirmar a escrita
db.collection.insertOne(
{ user: “Duarte”, status: “active” },
{ writeConcern: { w: “majority”, j: true, wtimeout: 5000 } }
)
// w: “majority” — escrita confirmada pela maioria das réplicas
// j: true — confirmação no journal (durabilidade)

Referência: MongoDB — documentação oficial.

6. Cassandra — O Colunar Distribuído para Escritas Massivas

O Apache Cassandra é um banco colunar distribuído, AP no teorema CAP, optimizado para escritas massivas em múltiplos datacenters. Não tem master — todos os nós são iguais.

Quando escolher Cassandra

Cenário Porquê
IoT / dados de sensores Escritas massivas (milhões/sec), dados temporais
Timeline / feed de rede social Escrita rápida, leitura por partition key
Log de eventos distribuído Multi-datacenter, sem master, sem ponto de falha
Sistema que não pode parar AP — sempre disponível mesmo com partições de rede

Quando NÃO escolher Cassandra

  • Transacções ACID — Cassandra não suporta transacções multi-linha
  • Queries ad-hoc flexíveis — Cassandra requer modelação de query prévia
  • Consistência forte — Cassandra é eventualmente consistente por defeito
  • Dados relacionais com joins — Cassandra não suporta joins

Modelo de dados Cassandra (partition key é crítica)

— Cassandra — modelação orientada a queries
— A partition key determina em que nó os dados são armazenados

— Cenário: timeline de mensagens por utilizador
CREATE TABLE messages (
user_id UUID, — partition key
message_time TIMESTAMP, — clustering key
sender UUID,
content TEXT,
PRIMARY KEY (user_id, message_time)
);

— Query eficiente: todas as mensagens de um utilizador
— (lê de uma única partição — rápida)
SELECT * FROM messages
WHERE user_id = 550e8400-e29b-41d4-a716-446655440000
ORDER BY message_time DESC
LIMIT 50;

— Query INEFICIENTE: todas as mensagens de um remetente
— (lê todas as partições — lenta)
SELECT * FROM messages WHERE sender = 550e8400;
— → Criar tabela auxiliar indexada por sender

Referência: Cassandra — documentação oficial.

7. DynamoDB — O Chave-Valor Gerido da AWS

O DynamoDB é um banco chave-valor gerido (serverless) da AWS. É AP no teorema CAP, com consistência eventual por defeito e consistência forte opcional.

Quando escolher DynamoDB

Cenário Porquê
Aplicação serverless na AWS Integração nativa com Lambda, API Gateway, AppSync
Sessões de utilizador TTL nativo, baixa latência (< 10ms)
Carregamento variável Auto-scaling automático — sem planeamento de capacidade
Sistema com requisitos simples de acesso Chave-valor, sem queries complexas

Quando NÃO escolher DynamoDB

  • Queries complexas ou ad-hoc — DynamoDB requer design de access patterns prévio
  • Transacções multi-item — suporta mas é limitado e caro
  • Múltiplos índices secundários — custos elevados (GB-sec e write units)
  • Aplicação multi-cloud — DynamoDB é AWS-only

Configuração de consistência

import boto3

dynamodb = boto3.resource(‘dynamodb’)
table = dynamodb.Table(‘users’)

# Consistência forte (CP) — lê a cópia mais recente
response = table.get_item(
Key={‘user_id’: ‘123’},
ConsistentRead=True
)

# Consistência eventual (AP) — mais rápida, pode estar desactualizada
response = table.get_item(
Key={‘user_id’: ‘123’},
ConsistentRead=False # padrão
)

# Transacção ACID (multi-item) — limitada a 25 items
response = dynamodb.meta.client.transact_write_items(
TransactItems=[
{‘Put’: {‘TableName’: ‘users’, ‘Item’: {‘user_id’: ‘123’, ‘balance’: 100}}},
{‘Update’: {‘TableName’: ‘accounts’, ‘Key’: {‘account_id’: ‘A1’},
‘UpdateExpression’: ‘SET balance = balance – :val’,
‘ConditionExpression’: ‘balance >= :val’,
‘ExpressionAttributeValues’: {‘:val’: 50}}}
]
)

Referência: DynamoDB — AWS.

8. CockroachDB — O NewSQL com Consistência Global

O CockroachDB é um banco NewSQL que combina a interface SQL do PostgreSQL com escalabilidade horizontal e consistência forte (CP). É o único banco desta lista que oferece ACID distribuído sem master.

Quando escolher CockroachDB

Cenário Porquê
Aplicação financeira global ACID distribuído, consistência forte multi-região
Sistema que precisa de SQL + escala horizontal PostgreSQL-compatible, distribuído
Multi-região com baixa latência Replica dados geograficamente próximos do utilizador
Migração de PostgreSQL com necessidade de escala Compatible com PostgreSQL wire protocol

Quando NÃO escolher CockroachDB

  • Custo — CockroachDB Cloud é significativamente mais caro que PostgreSQL
  • Escritas massivas simples — Cassandra é mais eficiente para escrita pura
  • Aplicação single-region pequena — PostgreSQL é mais simples e barato
  • Latência ultra-baixa — o consenso distribuído (Raft) adiciona latência

Configuração multi-região

— CockroachDB — configuração de sobrevivência multi-região
— Sobreviver a falha de região completa
ALTER DATABASE appdb CONFIGURE ZONE USING
num_replicas = 5,
constraints = ‘{“+region=eu-west1”:1, “+region=us-east1”:1, “+region=asia-east1”:1}’;

— Particionar tabela por região para baixa latência
CREATE TABLE orders (
id UUID PRIMARY KEY,
region STRING NOT NULL,
amount DECIMAL,
created_at TIMESTAMP
) PARTITION BY LIST (region) (
PARTITION eu VALUES IN (‘eu-west1’),
PARTITION us VALUES IN (‘us-east1’),
PARTITION asia VALUES IN (‘asia-east1’)
);

— Cada partição tem réplicas na sua região — leituras locais
ALTER TABLE orders CONFIGURE ZONE USING
num_replicas = 3,
constraints = ‘{“+region=eu-west1”:1, “+region=us-east1”:1, “+region=asia-east1”:1}’;

Referência: CockroachDB — documentação oficial.

9. Redis e SQLite — Casos Específicos

Redis — Cache e Chave-Valor em Memória

O Redis é um banco em memória, sub-millissegundo de latência. Não é um banco primário — é uma camada de cache, sessões, filas e contadores.

# Redis — casos de uso típicos

# Cache de query de base de dados
SET cache:user:123:profile ‘{“name”:”Duarte”,”role”:”admin”}’ EX 3600
GET cache:user:123:profile

# Sessões com TTL automático
SET session:abc123 ‘{“user_id”:123,”last_access”:”2026-07-13″}’ EX 1800

# Contador atómico (rate limiting)
INCR api:rate:user:123:20260713
EXPIRE api:rate:user:123:20260713 86400

# Pub/sub para notificações em tempo real
SUBSCRIBE notifications:user:123
PUBLISH notifications:user:123 ‘{“type”:”message”,”from”:456}’

Quando usar Redis Quando não usar
Cache de queries frequentes Armazenamento primário de dados persistentes
Sessões de utilizador Dados que precisam de ACID
Rate limiting Dados que não cabem em memória
Filas de tarefas Dados relacionais com joins
Leaderboards (sorted sets) Consultas complexas

Referência: Redis — documentação oficial.

SQLite — O Banco Embutido

O SQLite é um banco relacional embutido — um ficheiro, sem servidor. ACID completo, suporta bases de dados até 281 TB.

— SQLite — ideal para aplicações embutidas, mobile, protótipos

— Criar base de dados (é um ficheiro)
sqlite3 app.db

— Operações normais de SQL
CREATE TABLE config (
key TEXT PRIMARY KEY,
value TEXT NOT NULL,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

— WAL mode para concorrência de leitura
PRAGMA journal_mode=WAL;

— Verificar integridade
PRAGMA integrity_check;

Quando usar SQLite Quando não usar
Aplicação mobile Múltiplos escritores concorrentes
Protótipo ou MVP Servidor partilhado por múltiplas aplicações
Configuração local Escrita distribuída
Aplicação desktop Multi-utilizador simultâneo
Base de dados de teste Escala horizontal

Referência: SQLite — documentação oficial.

10. Cenários Reais — Que Banco Escolher

Cenário 1: Aplicação Financeira (banco/fintech)

Requisitos:
– Transacções ACID obrigatórias
– Consistência forte — saldo não pode estar incorrecto
– Disponibilidade 99.9%
– Auditoria e compliance

Escolha: PostgreSQL (single-region) ou CockroachDB (multi-region)
Cache: Redis para sessões e cache de saldos

Camada Banco Razão
Transacções PostgreSQL / CockroachDB ACID, consistência forte
Cache de saldo Redis Baixa latência (< 1ms)
Auditoria PostgreSQL (append-only table) Durabilidade, imutabilidade
Notificações Redis Pub/Sub Tempo real

Cenário 2: E-commerce

Requisitos:
– Catálogo com atributos variáveis (cada produto tem atributos diferentes)
– Carrinho de compras
– Pedidos transaccionais
– Busca full-text

Escolha: PostgreSQL (pedidos, pagamentos) + MongoDB (catálogo) + Elasticsearch (busca)

Camada Banco Razão
Catálogo MongoDB Schema flexível por produto
Pedidos/Pagamentos PostgreSQL ACID, transacções
Carrinho Redis TTL, baixa latência
Busca Elasticsearch Full-text, facets, filtros
Sessões Redis TTL automático

Cenário 3: Rede Social

Requisitos:
– Timeline/feed de milhões de utilizadores
– Escritas massivas (posts, likes, comentários)
– Disponibilidade > consistência
– Multi-região

Escolha: Cassandra (timeline, posts) + PostgreSQL (perfil, mensagens) + Redis (cache, sessions)

Camada Banco Razão
Timeline/feed Cassandra Escritas massivas, AP, multi-DC
Perfil, mensagens PostgreSQL Dados estruturados, relações
Cache de feed Redis Baixa latência para feed
Notificações Redis Pub/Sub Tempo real
Amizades/relações Neo4j (opcional) Relações complexas

Cenário 4: IoT / Telemetria

Requisitos:
– Milhões de sensores a escrever dados por segundo
– Leitura por dispositivo e janela temporal
– Dados temporais com retenção configurável
– Multi-datacenter

Escolha: Cassandra ou TimescaleDB (PostgreSQL extension)

Camada Banco Razão
Telemetria Cassandra Escritas massivas, AP, multi-DC
Alertas Redis Baixa latência, pub/sub
Dashboard TimescaleDB / ClickHouse Agregações temporais
Configuração PostgreSQL Dados estruturados

11. Erros Comuns na Escolha de Banco de Dados

  • “Usar PostgreSQL para tudo” — PostgreSQL é excelente, mas não é a melhor escolha para escritas massivas distribuídas (Cassandra), cache (Redis) ou busca full-text (Elasticsearch).
  • “MongoDB é mais rápido que SQL” — depende da query. PostgreSQL com índices correctos é frequentemente mais rápido que MongoDB para queries com filtros e ordenação.
  • “NoSQL não tem schema, logo é mais flexível” — a flexibilidade cria dívida técnica. Sem schema, a validação passa para a aplicação, e dados inválidos podem entrar silenciosamente.
  • “Cassandra serve para qualquer coisa que seja NoSQL” — Cassandra requer modelação orientada a queries. Não suporta queries ad-hoc eficientes. Se não sabes as queries antecipadamente, não uses Cassandra.
  • “CockroachDB é PostgreSQL distribuído” — CockroachDB é compatible com PostgreSQL wire protocol, mas não é um drop-in replacement. Algumas features do PostgreSQL não são suportadas (stored procedures em PL/pgSQL, extensões como PostGIS).
  • “DynamoDB é barato porque é serverless” — DynamoDB é barato para cargas baixas, mas custos escalam rapidamente com índices secundários, leituras fortes e armazenamento. Para cargas previsíveis, uma instância EC2 com PostgreSQL pode ser 10x mais barata.
  • “Redis é um banco de dados” — Redis é um banco em memória. Se o Redis cai e não tem persistência configurada (AOF/RDB), perde-se tudo. Usar Redis como cache, não como armazenamento primário.
  • “Escolher pelo que a equipa já conhece” — a curva de aprendizagem existe, mas a escolha errada causa problemas que nenhuma optimização resolve. Se a aplicação precisa de Cassandra e a equipa só sabe PostgreSQL, formar a equipa ou contratar — não forçar PostgreSQL num cenário que precisa de escrita distribuída.

12. Checklist de Decisão

  1. Tipo de dados — estruturado (SQL), semi-estruturado (documento), chave-valor, temporal?
  2. Consistência — forte (ACID) ou eventual (BASE) é aceitável?
  3. Teorema CAP — CP (consistência) ou AP (disponibilidade) em partição?
  4. Padrão de acesso — leitura/escrita, OLTP/OLAP, por ID/scan, ad-hoc/pré-definido?
  5. Escala — single-node ou distribuído? Escala horizontal necessária?
  6. Multi-região — precisa de baixa latência em múltiplas regiões?
  7. Transacções — multi-item ACID necessário? Quantos items por transacção?
  8. Schema — fixo (SQL), flexível (NoSQL), ou híbrido (PostgreSQL JSONB)?
  9. Queries — conheço as queries antecipadamente? (Cassandra) ou preciso de flexibilidade? (PostgreSQL)
  10. Custo — licenciamento, infraestrutura, operação, formação da equipa
  11. Ecossistema — drivers, ORM, ferramentas, comunidade, suporte
  12. Latência — sub-ms (Redis), < 10ms (DynamoDB), < 100ms (PostgreSQL remoto)
  13. Durabilidade — síncrona (PostgreSQL synchronous_commit) ou assíncrona (Cassandra)?
  14. Testar com dados reais — fazer benchmark com o padrão de acesso real antes de decidir
  15. Documentar a decisão — registar critérios, alternativas consideradas e razão da escolha

13. Artigos Relacionados

Este artigo foi útil?

Duarte Spínola

Deixe um Comentário