Qual banco de dados escolher? Antes de pensar em SQL ou NoSQL, pense nos padrões de acesso
Quando estamos começando a estudar banco de dados, é muito comum cair naquela discussão clássica:
“SQL é melhor que NoSQL?”
“MongoDB escala mais que PostgreSQL?”
“Redis é banco ou cache?”
“Preciso de consistência forte ou eventual consistency?”
Mas, na prática, a pergunta mais importante geralmente não é:
Qual banco é melhor?
E sim:
Qual banco atende melhor aos padrões de acesso e às garantias que o meu sistema precisa?
Porque banco de dados não é só sobre guardar informação. É sobre como essa informação será escrita, lida, consultada, escalada e protegida contra inconsistências.
Antes de escolher o banco, entenda o seu sistema
Antes de sair escolhendo PostgreSQL, MongoDB, Redis, DynamoDB, Cassandra ou qualquer outro, eu gosto de olhar para alguns pontos:
- Qual é o formato dos dados?
- Como esses dados serão acessados?
- O sistema lê mais ou escreve mais?
- A latência precisa ser muito baixa?
- Preciso de transações?
- Preciso de consistência forte?
- O sistema precisa escalar horizontalmente?
- O sistema tolera dados temporariamente inconsistentes?
- Qual é o impacto se uma leitura vier desatualizada?
Essas perguntas parecem simples, mas elas mudam completamente a escolha do banco.
Padrão de acesso vem antes da modelagem
Um erro comum é começar pensando na estrutura da tabela ou do documento antes de entender as consultas principais do sistema.
Por exemplo, imagine um sistema de estoque.
Você pode precisar responder perguntas como:
- Quantos produtos existem no total?
- Quais produtos estão com baixo estoque?
- Qual foi o histórico de movimentações de um produto?
- Quem fez determinada alteração?
- Qual empresa é dona daquele SKU?
- Preciso garantir que o SKU seja único por empresa?
- Preciso evitar que duas baixas simultâneas deixem o estoque negativo?
Percebe que a escolha do banco começa a depender menos de “SQL vs NoSQL” e mais de quais garantias o domínio exige?
Se eu preciso de integridade, transações e regras fortes, provavelmente um banco relacional como PostgreSQL faz bastante sentido.
Se eu preciso armazenar preferências flexíveis de usuário, logs ou documentos com formatos variados, talvez um banco orientado a documentos resolva melhor.
Se eu preciso de leitura extremamente rápida para sessão, cache ou rate limit, talvez Redis seja mais adequado.
Quando SQL faz muito sentido
Bancos relacionais, como PostgreSQL e MySQL, são muito fortes quando você precisa de:
- dados estruturados;
- relacionamentos claros;
- queries complexas;
- transações;
- integridade referencial;
- consistência forte;
- regras de negócio críticas.
Exemplos de sistemas onde SQL costuma encaixar muito bem:
- financeiro;
- ERP;
- CRM;
- marketplace;
- controle de estoque;
- pedidos;
- pagamentos;
- sistemas administrativos.
Em um banco relacional, você consegue trabalhar bem com constraints, foreign keys, joins, índices, transações e isolamento.
Por exemplo, se o usuário está fazendo uma compra, talvez você precise:
- criar o pedido;
- baixar o estoque;
- registrar o pagamento;
- gerar uma movimentação;
- atualizar o saldo.
Se uma dessas etapas falhar, talvez nenhuma delas deva ser persistida.
Esse é um cenário onde as garantias ACID são muito importantes.
O papel do ACID
ACID representa quatro garantias importantes em transações:
- Atomicity: tudo acontece ou nada acontece.
- Consistency: o banco não deve sair de um estado válido para um estado inválido.
- Isolation: transações simultâneas não devem interferir incorretamente umas nas outras.
- Durability: depois que foi salvo, deve sobreviver a falhas.
Isso é muito importante quando o erro custa caro.
Se um sistema financeiro debita dinheiro de uma conta, mas não credita na outra, temos um problema grave.
Se um sistema de estoque permite duas vendas simultâneas do último item disponível, também temos um problema.
Nesses casos, consistência não é detalhe técnico. É regra de negócio.
As dificuldades do SQL
Mas SQL também tem seus desafios.
Normalmente, bancos relacionais escalam muito bem verticalmente, colocando mais CPU, memória e disco na máquina. Porém, escalar writes distribuídos pode ser mais complexo.
Também existe um custo natural quando o domínio começa a crescer muito:
- joins pesados;
- locks;
- migrações de schema;
- modelagens muito rígidas;
- dificuldade para distribuir escrita em múltiplos nós.
Não significa que SQL é ruim. Muito pelo contrário. Mas significa que ele também tem trade-offs.
Quando NoSQL faz sentido
NoSQL não significa “melhor que SQL”. Significa que o banco foi pensado para outros tipos de problema.
Bancos NoSQL costumam ser úteis quando você precisa de:
- schema flexível;
- alta escala;
- alto throughput;
- dados sem estrutura fixa;
- baixa latência;
- distribuição horizontal;
- tolerância a consistência eventual.
Exemplos:
Document Database
Como MongoDB.
Bom para dados em formato de documento, como:
{
"id": "user_123",
"name": "Luis",
"settings": {
"theme": "dark",
"language": "pt-BR",
"notifications": true
}
}
Esse tipo de estrutura pode ser bem natural para preferências de usuário, perfis, configurações e dados semi-estruturados.
Key-Value Store
Como Redis ou DynamoDB em alguns cenários.
Muito usado para:
- cache;
- sessões;
- feature flags;
- rate limits;
- chaves de idempotência;
- filas simples;
- dados acessados por chave.
Exemplo:
rate_limit:user_123 -> 58 requests
session:abc123 -> user data
feature:new_dashboard:user_123 -> true
Aqui o padrão de acesso geralmente é direto:
Tenho uma chave e quero buscar o valor rapidamente.
Columnar / Wide-column
Como Cassandra, Bigtable ou HBase.
Costuma fazer sentido em cenários de:
- grande volume de dados;
- escrita massiva;
- dados distribuídos;
- séries temporais;
- analytics em escala.
Não é o tipo de banco que eu escolheria para qualquer CRUD simples, mas pode ser excelente quando o problema exige alto volume e distribuição.
Graph Database
Como Neo4j.
Faz sentido quando os relacionamentos são a parte mais importante do domínio.
Exemplos:
- redes sociais;
- recomendações;
- fraude;
- mapas de dependência;
- conexões entre entidades.
Se a pergunta principal do sistema é algo como:
“Quais usuários estão conectados indiretamente com esse usuário?”
Um banco de grafos pode ser muito melhor que tentar resolver isso com várias tabelas relacionais e joins recursivos.
Vector Database
Como Pinecone, Weaviate, Milvus ou pgvector no PostgreSQL.
Muito usado em aplicações com IA, principalmente RAG.
Serve para buscar dados por similaridade semântica.
Exemplo:
“Encontre documentos parecidos com essa pergunta.”
Em vez de buscar apenas por palavra-chave, o sistema busca por proximidade vetorial.
Isso é muito útil para chatbots com base de conhecimento, busca semântica, recomendação e recuperação de contexto para LLMs.
CAP também entra na conversa
Quando falamos de sistemas distribuídos, o CAP Theorem começa a aparecer.
Ele fala sobre três propriedades:
- Consistency
- Availability
- Partition Tolerance
Em sistemas distribuídos, quando ocorre uma partição de rede, você geralmente precisa escolher entre priorizar consistência ou disponibilidade.
Ou seja:
- prefiro recusar ou atrasar respostas para garantir dados corretos?
- ou prefiro continuar respondendo, mesmo que algum dado esteja temporariamente desatualizado?
Essa escolha depende do sistema.
Em um feed de rede social, talvez não tenha problema uma curtida aparecer alguns segundos depois.
Em uma transferência bancária, isso pode ser inaceitável.
Consistência eventual não é bagunça
Muita gente escuta “eventual consistency” e pensa:
“Então o dado pode ficar errado?”
Não exatamente.
Consistência eventual significa que o sistema pode ficar temporariamente inconsistente, mas, se não houver novas alterações, os dados tendem a convergir para um estado consistente.
Isso é comum em sistemas distribuídos que priorizam disponibilidade e escala.
Exemplo simples:
Você altera sua foto de perfil.
Talvez em um serviço a foto nova apareça imediatamente, mas em outro ela demore alguns segundos.
Isso geralmente é aceitável.
Agora imagine isso em um saldo bancário.
Aí o nível de exigência muda completamente.
Read-heavy vs Write-heavy
Outro ponto importante é entender se o sistema lê mais ou escreve mais.
Um sistema read-heavy pode se beneficiar muito de:
- cache;
- read replicas;
- materialized views;
- índices bem planejados;
- CDN, dependendo do tipo de dado.
Já um sistema write-heavy precisa tomar cuidado com:
- contenção;
- locks;
- particionamento;
- filas;
- consistência;
- throughput de escrita.
Um exemplo:
Um blog ou portal de notícias provavelmente lê muito mais do que escreve.
Já um sistema de logs, métricas ou eventos pode escrever milhares de registros por segundo.
São problemas bem diferentes.
Latência também muda a escolha
Às vezes, a questão nem é só consistência. É tempo de resposta.
Se eu preciso validar uma sessão de usuário em toda request, talvez buscar isso em um banco relacional toda vez não seja o melhor caminho.
Redis pode ser uma escolha melhor para esse tipo de acesso rápido.
Mas isso não significa que Redis substitui o banco principal.
Muitas vezes a melhor arquitetura usa mais de um banco, cada um para uma responsabilidade.
Um exemplo prático
Imagine um SaaS de estoque.
Eu provavelmente usaria PostgreSQL como banco principal, porque preciso de:
- empresas;
- usuários;
- produtos;
- categorias;
- SKUs únicos por empresa;
- movimentações de estoque;
- histórico;
- regras de integridade;
- transações.
Mas eu também poderia usar Redis para:
- cache de dashboard;
- sessões;
- rate limit;
- filas temporárias;
- notificações em tempo real.
E talvez, no futuro, usar um banco vetorial para:
- busca inteligente em produtos;
- assistente com IA;
- perguntas em linguagem natural sobre estoque;
- RAG em documentos internos.
Perceba que a pergunta deixa de ser:
“Qual banco eu uso?”
E vira:
“Qual responsabilidade cada banco precisa cumprir?”
Uma forma simples de pensar
Eu gosto de pensar assim:
Se o sistema precisa de consistência forte, relacionamentos e transações, SQL provavelmente é uma ótima escolha.
Se o sistema precisa de schema flexível e documentos variáveis, um document database pode fazer sentido.
Se o sistema precisa de baixa latência por chave, um key-value store pode ser melhor.
Se o sistema precisa de relacionamentos complexos, graph database pode encaixar.
Se o sistema precisa de busca semântica e IA, vector database entra na conversa.
Se o sistema precisa de grande volume analítico, bancos colunares podem ser melhores.
Conclusão
Escolher banco de dados não é escolher o mais famoso, o mais moderno ou o que aparece mais em vídeo no YouTube.
É entender:
- o formato dos dados;
- os padrões de acesso;
- a frequência de leitura e escrita;
- a latência esperada;
- as garantias necessárias;
- os riscos de inconsistência;
- os trade-offs de escala.
No fim, banco de dados é uma decisão de arquitetura.
E toda decisão de arquitetura é sobre trade-off.
Às vezes PostgreSQL resolve 95% do problema com segurança e simplicidade.
Às vezes MongoDB faz mais sentido.
Às vezes Redis é indispensável.
Às vezes você vai usar todos eles no mesmo sistema.
O segredo é não começar pela tecnologia.
Comece pelo comportamento que o seu sistema precisa ter.