Bancos de dados
Como bancos de dados armazenam, organizam e recuperam de forma confiável dados persistentes dos quais as aplicações dependem.
Por que os bancos de dados existem
A memória da aplicação é temporária. Sistemas reais exigem armazenamento durável que sobreviva a falhas, reinicializações e deploys.
- A memória do servidor (RAM) é volátil e é limpa quando o processo para.
- Dados críticos — usuários, pedidos, mensagens, logs — precisam persistir além da execução.
- Um banco de dados fornece armazenamento durável e estruturado, apoiado por disco.
Detalhes
Um servidor backend é apenas um processo em execução sob o controle do sistema operacional. Suas variáveis em memória desaparecem quando o processo reinicia, falha ou é redeployado. Isso torna a memória ideal para computação, mas completamente não confiável para armazenamento de longo prazo.
Sistemas em produção exigem durabilidade dos dados. Contas de usuário ainda devem existir após uma reinicialização. Pedidos devem continuar registrados após um deploy. Logs devem permanecer acessíveis para depuração e auditoria.
Um banco de dados resolve isso gravando dados estruturados em armazenamento persistente (normalmente SSD ou disco). Enquanto a memória é otimizada para velocidade, o armazenamento é otimizado para durabilidade. O mecanismo do banco de dados gerencia como os dados são gravados, indexados e recuperados com segurança.
Sem um banco de dados, seu sistema não tem memória de longo prazo. Ele se torna stateless da pior forma possível — incapaz de sobreviver a falhas.
O que é um banco de dados?
Um banco de dados é um sistema gerenciado que armazena dados de forma durável, os organiza com estrutura e permite recuperação controlada.
- Persiste dados de forma confiável em disco além da vida útil do processo.
- Organiza os dados em modelos estruturados (tabelas, documentos, chave-valor).
- Fornece um mecanismo de consulta e impõe restrições para garantir a integridade.
Detalhes
Um banco de dados não é apenas armazenamento; é um mecanismo de execução controlado para dados.
No modelo relacional, os dados são armazenados em tabelas compostas por linhas e colunas. Cada linha representa um registro, e cada coluna representa um atributo. Um schema define a estrutura, os tipos de dados e as restrições, evitando que dados inválidos ou inconsistentes sejam inseridos.
O banco de dados também fornece um mecanismo de consulta. Em vez de ler arquivos brutos, as aplicações emitem consultas estruturadas para recuperar ou modificar subconjuntos específicos de dados de forma eficiente.
Em nível de sistema, o banco de dados é a fonte autoritativa da verdade. Ele garante durabilidade, mantém a integridade estrutural e permite um gerenciamento de estado previsível.
SQL vs NoSQL
Bancos de dados SQL e NoSQL resolvem problemas de armazenamento semelhantes com diferentes trade-offs de estrutura e escalabilidade — nenhum é universalmente superior.
- SQL: Esquema estruturado, modelo baseado em tabelas, fortes garantias de consistência.
- NoSQL: Esquema flexível, geralmente baseado em documentos ou chave-valor, projetado para escalabilidade horizontal.
Detalhes
Bancos de dados SQL (sistemas relacionais) organizam os dados em tabelas predefinidas com esquemas rígidos. As relações entre tabelas são modeladas explicitamente, e fortes garantias transacionais são padrão. Isso os torna muito adequados para sistemas que exigem integridade e consultas complexas.
Bancos de dados NoSQL flexibilizam esquemas rígidos. Muitos usam estruturas baseadas em documentos ou chave-valor, permitindo que os campos variem entre registros. Essa flexibilidade pode simplificar o desenvolvimento para modelos de dados que evoluem rapidamente e pode oferecer suporte à escalabilidade horizontal em clusters distribuídos de forma mais natural.
A diferença real está na ênfase arquitetural. SQL prioriza estrutura e forte consistência. NoSQL prioriza flexibilidade e escalabilidade distribuída. Sistemas em produção frequentemente combinam ambos, dependendo da carga de trabalho.
O que acontece quando um servidor consulta um banco de dados?
Na maioria dos sistemas reais, a chamada ao banco de dados — e não a lógica da aplicação — domina a latência da requisição.
- O fluxo da requisição se estende: Cliente → Load Balancer → Servidor → Banco de Dados → Servidor → Cliente.
- O servidor fica bloqueado (ou aguardando) enquanto o banco processa a consulta.
- As idas e voltas ao banco de dados muitas vezes determinam o tempo total de resposta.
Detalhes
Quando um cliente envia uma requisição HTTP, ela eventualmente chega ao processo do seu servidor. Seu handler executa a lógica da aplicação — mas a maioria das operações relevantes exige ler ou gravar dados persistentes.
O servidor envia uma consulta para o mecanismo do banco de dados. Essa consulta pode envolver analisar SQL, verificar permissões, localizar páginas de dados relevantes, usar índices, ler do disco e montar um conjunto de resultados.
Durante esse tempo, a thread do servidor normalmente fica aguardando. Em modelos síncronos, ela fica bloqueada. Em modelos assíncronos, o event loop aguarda o resultado. De qualquer forma, o progresso depende de o banco concluir seu trabalho.
Isso é crítico: a interação com o banco de dados frequentemente é o maior fator de latência em sistemas de backend. Consultas ruins, índices ausentes, idas e voltas pela rede ou atrasos de I/O em disco podem facilmente superar o tempo de computação da aplicação.
Se o seu sistema parece lento, a camada de banco de dados costuma ser o primeiro lugar a investigar.
Indexação
Um índice ajuda o banco de dados a encontrar dados rapidamente sem verificar cada linha individualmente.
- Sem índice → o banco de dados verifica as linhas uma por uma.
- Com um índice → o banco de dados vai diretamente para os dados correspondentes.
- Índices aceleram leituras, mas adicionam trabalho extra ao gravar dados.
Detalhes
Suponha que você tenha uma tabela com um milhão de usuários e pesquise um endereço de e-mail específico.
Sem um índice, o banco de dados pode precisar examinar cada linha até encontrar uma correspondência. Isso é lento — especialmente à medida que a tabela cresce.
Com um índice na coluna de e-mail, o banco de dados mantém uma estrutura separada e organizada (semelhante ao índice de um livro). Em vez de varrer tudo, ele usa essa estrutura para localizar rapidamente a linha correta.
Índices tornam as leituras muito mais rápidas, mas eles não são gratuitos. Toda vez que você insere, atualiza ou exclui dados, o índice também precisa ser atualizado.
Se uma consulta estiver inesperadamente lenta, uma das primeiras perguntas a fazer é: “Existe um índice na coluna que está sendo pesquisada?”
Transações & Consistência
Uma transação garante que um grupo de operações relacionadas ou seja concluído com sucesso em conjunto, ou falhe em conjunto.
As etapas são executadas sequencialmente. Se uma falhar, toda alteração anterior é revertida para que o banco de dados nunca termine em um estado parcialmente atualizado.
- Múltiplas operações de banco de dados podem ser agrupadas em uma única unidade lógica.
- Se uma etapa falhar, todas as alterações anteriores são desfeitas.
- Isso protege os dados de ficarem em um estado parcialmente atualizado.
Detalhes
Considere transferir dinheiro da Conta A para a Conta B.
Etapa 1: Subtrair $100 da Conta A.
Etapa 2: Adicionar $100 à Conta B.
Se o sistema travar depois da Etapa 1, mas antes da Etapa 2, o dinheiro desaparece. Isso é corrupção de dados.
Uma transação impede isso. Ambas as operações são encapsuladas dentro de um limite transacional. O banco de dados garante que:
• Ambas as etapas sejam concluídas com sucesso, ou
• Nenhuma das etapas seja aplicada permanentemente.
Esse comportamento de “tudo ou nada” é chamado de atomicidade. Ele garante que o sistema permaneça logicamente consistente mesmo durante falhas.
Transações são essenciais em qualquer lugar onde a correção dos dados importa — finanças, estoque, autenticação e muito mais.
ACID
ACID define as quatro garantias que mantêm as transações de banco de dados corretas e resistentes a falhas.
- Atomicidade: Uma transação é concluída com sucesso por completo ou é totalmente revertida.
- Consistência: Os dados permanecem válidos após uma transação confirmada.
- Isolamento: Transações concorrentes não corrompem umas às outras.
- Durabilidade: Os dados confirmados sobrevivem a falhas e reinicializações.
Detalhes
ACID é um contrato prático de confiabilidade, não teoria.
Atomicidade impede atualizações parciais. Se uma etapa falhar, tudo é revertido.
Consistência garante que restrições, relacionamentos e regras sejam preservados após a conclusão de uma transação.
Isolamento protege as transações para que não corrompam umas às outras quando vários usuários operam simultaneamente.
Durabilidade garante que, assim que o banco de dados confirmar o sucesso, os dados sejam gravados em armazenamento persistente e sobrevivam a falhas do sistema.
Juntas, essas propriedades tornam os bancos de dados bases confiáveis para sistemas do mundo real.
Escalando Bancos de Dados
À medida que o tráfego e os dados crescem, uma única instância de banco de dados muitas vezes se torna um gargalo. Estratégias de escalabilidade distribuem a carga ou aumentam a capacidade.
- Escalonamento vertical aumenta o poder de uma única máquina de banco de dados.
- Réplicas de leitura distribuem o tráfego de leitura entre várias cópias dos dados.
- Sharding divide os dados entre vários bancos de dados para distribuir a carga total.
Detalhes
À medida que o uso cresce, o volume de consultas aumenta. Eventualmente, um único servidor de banco de dados não consegue acompanhar as requisições recebidas.
Uma abordagem é o escalonamento vertical — atualizar a máquina existente com mais CPU, memória ou armazenamento mais rápido. Esta é a solução mais simples porque a arquitetura permanece a mesma. No entanto, as atualizações de hardware têm limites e os custos aumentam rapidamente.
Outra estratégia é adicionar réplicas de leitura. Nesse modelo, um banco de dados primário lida com as gravações enquanto cópias replicadas atendem consultas somente leitura. Isso reduz a pressão sobre o servidor primário, embora possa introduzir pequenos atrasos à medida que os dados se propagam entre os nós.
Para um crescimento ainda maior, os sistemas podem usar sharding. Em vez de armazenar todos os dados em uma máquina, o conjunto de dados é dividido entre várias instâncias de banco de dados. Por exemplo, um shard pode armazenar usuários de A–M e outro de N–Z. Isso aumenta a capacidade total, mas exige lógica de roteamento cuidadosa e gerenciamento operacional.
Cada uma dessas abordagens melhora a escalabilidade, mas também introduz trade-offs em custo, complexidade e consistência.
Falhas e Gargalos do Banco de Dados
Quando o banco de dados fica lento ou falha, toda a aplicação sente o impacto imediatamente.
Aplicação
Requisições aguardando o BD
Condição do banco de dados
- Se o banco de dados ficar indisponível, as requisições começam a falhar imediatamente.
- Consultas lentas ou contenção de bloqueios fazem a latência aumentar em toda a aplicação.
- Esgotamento de recursos — conexões, disco ou atraso de replicação — leva à instabilidade.
Detalhes
O banco de dados costuma ser a dependência mais crítica em um sistema backend. Quando ele fica lento ou falha, a aplicação reflete o impacto imediatamente.
Se o banco de dados ficar inacessível, os handlers de requisição não conseguem concluir suas consultas e a aplicação começa a retornar erros de nível 500.
Mesmo quando o banco de dados está em execução, consultas lentas, índices ausentes ou contenção de bloqueios podem aumentar a latência. De fora, o servidor parece lento, mas na verdade está aguardando o banco de dados.
Sob carga pesada, limites de recursos como esgotamento de conexões, atraso de replicação ou saturação de disco podem introduzir instabilidade e comportamento inconsistente.
Muitos “problemas da aplicação” se originam na camada de persistência. Entender essa cadeia de dependência é essencial para diagnosticar problemas em produção.
Seção de Perguntas
1 / 5