Close Menu
Código Simples .NETCódigo Simples .NET
    Facebook X (Twitter) Instagram
    Trending
    • Context engineering: quando o problema deixa de ser prompt e vira arquitetura
    • Clean Code (2ª edição): o que mudou e o que continua valendo
    • Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha
    • Guia Profissional de Prompting – Domando um ChatGPT Preguiçoso: Como Obter Respostas Completas, Profundas e Confiáveis
    • A Anatomia de um Prompt: Como Falar com a IA Como um Profissional de Tecnologia
    • Conheça os tipos de registros DNS: o guia completo sobre A, AAAA, NS, CNAME, MX, PTR, SOA, TXT, SRV, SPF e muito mais
    • Cache além do básico: por que LRU e TTL precisam andar juntos
    • Quando usar arquitetura modular — e quando não usar
    Facebook X (Twitter) Instagram
    Código Simples .NETCódigo Simples .NET
    Código Simples .NETCódigo Simples .NET
    Home»Arquitetura»Bancos de dados e armazenamento: onde moram os gargalos

    Bancos de dados e armazenamento: onde moram os gargalos

    Jhonathan SoaresBy Jhonathan Soares6 de setembro de 20255 Mins Read Arquitetura
    Share
    Facebook Twitter LinkedIn WhatsApp Copy Link

    No primeiro artigo da série System Design: da teoria à prática, vimos que todo sistema é um conjunto de trade-offs. Falamos sobre latência, escalabilidade e adaptabilidade como princípios universais. Mas, na prática, onde esses trade-offs mais cedo ou mais tarde se manifestam?

    A resposta é quase sempre a mesma: nos bancos de dados e sistemas de armazenamento.

    É aqui que os gargalos aparecem primeiro, que os custos explodem e que a complexidade se multiplica. Não importa se você usa MySQL, Postgres, MongoDB ou DynamoDB: cedo ou tarde, você vai se deparar com problemas de índices, replicação, particionamento, consistência e cache.

    Neste segundo artigo da série, mergulhamos em cinco princípios fundamentais para entender como projetar sistemas de dados mais resilientes e escaláveis, sempre equilibrando teoria, prática e exemplos do mundo real.


    6. Índices são alavancas poderosas (e custosas)

    Índices são a ferramenta clássica para acelerar consultas. Eles criam uma estrutura auxiliar de dados (B-Tree, Hash, GiST, etc.) que o banco mantém para permitir buscas rápidas.

    • Benefício: consultas que poderiam varrer milhões de linhas passam a localizar registros em milissegundos.
    • Custo: cada escrita precisa também atualizar os índices, aumentando latência de inserção/atualização e consumo de disco.

    📚 Teoria:

    1. Database System Concepts (Silberschatz, Korth) detalha a estrutura de índices.
    2. Designing Data-Intensive Applications (Kleppmann) mostra trade-offs em workloads mistos.

    Exemplo real:
    Um e-commerce que indexa customer_id em uma tabela de pedidos melhora buscas de histórico. Mas indexar status em uma tabela com milhões de linhas, onde 95% são “completed”, gera mais custo que benefício — seletividade baixa.

    Boa prática: medir index hit ratio e eliminar índices pouco usados. Ferramentas como pg_stat_user_indexes (Postgres) ou sys.dm_db_index_usage_stats (SQL Server) ajudam a identificar “índices mortos”.


    7. Replicação ajuda leituras, particionamento ajuda escritas

    À medida que os dados crescem, chega o momento de escalar horizontalmente. Mas replicação e particionamento não resolvem o mesmo problema.

    Replicação

    • O que é: cópias idênticas dos dados em múltiplos nós.
    • Benefícios: melhora throughput de leitura, aumenta resiliência (failover).
    • Custos: escritas continuam centralizadas no primário, e réplicas assíncronas podem servir dados desatualizados.

    Exemplo: o Instagram usa Postgres com réplicas de leitura para dashboards e analytics. Assim, relatórios pesados não travam o nó primário.

    Particionamento (sharding)

    • O que é: dividir dados em múltiplos nós (cada shard armazena uma parte).
    • Benefícios: distribui escritas e armazenamento, escala quase “infinitamente”.
    • Custos: consultas que atravessam shards são caras, rebalanço é difícil, escolha errada de shard key gera hot partitions.

    Exemplo: o Twitter particiona dados por ID de usuário. Isso resolve escala de escrita, mas dificulta queries globais como “tweets com hashtag X”.

    Quando usar?

    • Workload dominado por leitura: replicação resolve.
    • Workload dominado por escrita: particionamento é inevitável.
    • Grandes players: combinam ambos (shards com réplicas internas).

    📚 Teoria:

    • CAP theorem (Brewer, 2000): replicar é escolher entre consistência e disponibilidade.
    • PACELC theorem (Abadi, 2010): mesmo sem falhas, há trade-off entre latência e consistência.
    • Google Spanner: particionamento em tablets + replicação sincronizada com relógios atômicos.

    Insight: replicação ≠ escala de escrita, particionamento ≠ simplicidade. É preciso diagnosticar onde dói mais antes de escolher.


    8. Dual writes são uma armadilha

    O padrão clássico: gravar em dois sistemas de forma independente.

    INSERT INTO orders ...
    PUBLISH order_created_event ...
    

    O problema: se um commit falha, você gera drift entre sistemas.

    📚 Teoria e soluções:

    • Outbox Pattern (Chris Richardson): salvar evento junto com a transação local e publicar depois via CDC.
    • Transactional outbox com Kafka + Debezium virou padrão de mercado.
    • Papers sobre atomic broadcast e distributed consensus mostram que atomicidade sem coordenação é impossível.

    Exemplo real: uma fintech brasileira sofreu inconsistências ao salvar transações em Postgres e Kafka separadamente. Resolveram adotando outbox + Debezium para replicar eventos com consistência.

    Insight: dual writes simples nunca são seguros. Use outbox, sagas ou coordenação transacional.


    9. Event stores vs filas: rastreabilidade vs simplicidade

    Filas (SQS, RabbitMQ) entregam mensagens e descartam. Event stores (Kafka, EventStoreDB) tratam eventos como imutáveis, preservados para replay.

    • Fila: simples, barata, ótima para jobs assíncronos.
    • Event store: mais complexa, mas permite reconstruir o estado e auditar histórico.

    📚 Teoria:

    • Event Sourcing (Martin Fowler) — o estado como resultado de eventos.
    • The Log: What Every Software Engineer Should Know About Real-Time Data (Jay Kreps).

    Exemplos reais:

    • Netflix usa Kafka como log de eventos de streaming.
    • Nubank usa Event Sourcing em contas correntes para rastreabilidade total.

    Insight: filas resolvem processos pontuais; event stores resolvem história.


    10. Cache invalidation: o problema eterno

    Invalidar cache é difícil porque é balancear freshness vs performance.

    Estratégias comuns

    • Write-through: grava banco e cache juntos.
    • Write-around: grava só no banco; cache expira.
    • Write-back: grava no cache e persiste depois.

    📚 Referências:

    • Phil Karlton: “There are only two hard things in Computer Science: cache invalidation and naming things.”
    • High Performance Browser Networking (Ilya Grigorik).
    • Blog da Cloudflare sobre TTL dinâmico.

    Exemplo real: Stack Overflow já enfrentou inconsistências porque caches regionais serviam dados obsoletos após updates críticos.

    Boa prática: medir stale hit ratio — quantas leituras servem dado velho — e ajustar TTL conforme SLA de frescor.


    Conclusão — onde os gargalos realmente moram

    Armazenamento é o coração da arquitetura. É aqui que os trade-offs deixam de ser teóricos e se tornam incidentes em produção: índices que pesam mais do que ajudam, replicações que entregam dados desatualizados, shards que criam hot partitions, dual writes que quebram consistência e caches que servem dados velhos.

    Resumo deste capítulo:

    • Índices: aceleram consultas, mas penalizam escritas.
    • Replicação: melhora leitura, mas não resolve escrita.
    • Particionamento: escala escrita, mas complica queries.
    • Dual writes: inconsistência garantida sem coordenação.
    • Event stores: rastreabilidade ao custo de simplicidade.
    • Cache invalidation: um dos problemas mais difíceis da computação.

    Este foi o Artigo 2 da série System Design: da teoria à prática.
    No próximo, vamos explorar Confiabilidade e Consistência — idempotência, eventual consistency, conflitos em sistemas ativos-ativos e o preço da durabilidade.

    database system-design
    Share. Facebook Twitter LinkedIn Telegram WhatsApp Copy Link
    Jhonathan Soares
    • Website
    • Facebook
    • X (Twitter)
    • LinkedIn

    Criador do blog Código Simples e com mais 15 anos de experiência em TI, com títulos de MVP Microsoft na área de Visual Studio Development, Neo4j Top 50 Certificate, Scrum Master e MongoDB Evangelist.

    Posts Relacionados

    Context engineering: quando o problema deixa de ser prompt e vira arquitetura

    Arquitetura IA 16 de abril de 202611 Mins Read

    Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha

    Arquitetura 4 de fevereiro de 20268 Mins Read

    Cache além do básico: por que LRU e TTL precisam andar juntos

    Arquitetura NoSql 7 de outubro de 20259 Mins Read
    Newsletter

    Digite seu endereço de e-mail para receber notificações de novas publicações por e-mail.

    Junte-se a 25mil outros assinantes
    Posts recentes
    • Context engineering: quando o problema deixa de ser prompt e vira arquitetura
    • Clean Code (2ª edição): o que mudou e o que continua valendo
    • Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha
    • Guia Profissional de Prompting – Domando um ChatGPT Preguiçoso: Como Obter Respostas Completas, Profundas e Confiáveis
    • A Anatomia de um Prompt: Como Falar com a IA Como um Profissional de Tecnologia
    Categorias
    • Arquitetura (31)
      • Microsserviços (3)
      • Testes (2)
    • Asp.net (120)
      • C# (89)
      • Mvc (13)
    • Banco de dados (93)
      • NoSql (60)
      • Sql (38)
    • Boas práticas (34)
      • Gestão & Produtividade (4)
      • Metodologias Ágeis (6)
    • Cursos (53)
    • Dicas (108)
    • Front-End (92)
    • IA (7)
    • Linux (6)
    • NodeJS (4)
    • Post do Leitor (9)
    • Python (5)
    • Seo (12)
    • Tecnologia (30)
      • ITIL (1)
      • Padrões de Projeto (4)
    • Testes (2)

    VEJA TAMBÉM

    Cursos
    12 de fevereiro de 20166 Mins Read

    1000 livros gratuitos sobre programação!

    Olha que dica bacana! A pagina só com livros sobre programação é mantida no GitHub…

    30 APIs Gratuitas para desenvolvedores

    Código Simples no Facebook
    Código Simples no Facebook
    • Popular
    • Recente

    1000 livros gratuitos sobre programação!

    12 de fevereiro de 2016

    Google lança versão “invisível” do reCAPTCHA!

    10 de março de 2017

    Mini curso de HTML5 oferecido pela Microsoft

    30 de janeiro de 2014

    O que significa ( !important ) na declaração do CSS ?

    5 de fevereiro de 2014

    Programa para supercompactar arquivos. KGB Archiver.

    6 de fevereiro de 2014

    Context engineering: quando o problema deixa de ser prompt e vira arquitetura

    16 de abril de 2026

    Clean Code (2ª edição): o que mudou e o que continua valendo

    12 de fevereiro de 2026

    Sunk Cost em Arquitetura de Software: como evitar que meses de investimento virem uma armadilha

    4 de fevereiro de 2026

    Guia Profissional de Prompting – Domando um ChatGPT Preguiçoso: Como Obter Respostas Completas, Profundas e Confiáveis

    30 de outubro de 2025

    A Anatomia de um Prompt: Como Falar com a IA Como um Profissional de Tecnologia

    30 de outubro de 2025
    Nosso Feed
    • RSS - Posts
    Fique por dentro

    Digite seu endereço de email para assinar este blog e receber notificações de novas publicações por email.

    Facebook X (Twitter) Instagram LinkedIn

    Type above and press Enter to search. Press Esc to cancel.

    Vá para versão mobile