image

Acesse bootcamps ilimitados e +750 cursos pra sempre

70
%OFF
Article image
Mateus Souza
Mateus Souza25/06/2026 13:04
Compartilhe

Você tem um monolito disfarçado.

    Banco de Dados por Serviço na Prática: Como Separar o Banco Sem Quebrar o que Já Existe

    Seu sistema tem microsserviços, mas todos apontam pro mesmo banco?

    Parabéns — você tem um monolito disfarçado. E eu sei disso porque trabalhei em um.

    O cenário real: 6 microsserviços, 1 banco, e uma fila de problemas

    Em uma de minhas atuações trabalhei com um sistema que processava até 100 mil requisições diárias. A arquitetura tinha microsserviços bem definidos por domínio:

    →  Orders — gestão das ordens de entrega logística

    →  Motoristas — cadastro, disponibilidade e rastreamento

    →  Financeiro — cálculo de frete, repasses e cobranças

    →  Notificação — envio de alertas para clientes e parceiros

    →  Integração — comunicação com sistemas externos e parceiros

    →  Averbação — registro e cobertura das entregas junto à seguradora

    Na teoria, cada um tinha sua responsabilidade clara. Na prática, todos apontavam para o mesmo banco PostgreSQL.

    Por um tempo, funcionou. O sistema cresceu, o volume aumentou, e o banco foi aguentando. Até o dia em que parou de aguentar.

    E quando um banco compartilhado começa a ceder sob carga, ele não avisa com antecedência.

    Os problemas que um banco compartilhado gera na prática

    O primeiro sintoma foi o mais silencioso: queries que antes demoravam milissegundos começaram a demorar segundos. Sem motivo aparente.

    A causa era clássica: o serviço de Orders rodava uma view materializada com alto volume de dados no mesmo momento em que o serviço Financeiro tentava executar queries transacionais. O banco tinha que gerenciar locks concorrentes entre operações que, conceitualmente, não tinham nada a ver uma com a outra — mas compartilhavam tabelas.

    Com o tempo, os problemas foram se acumulando:

    →  Travamentos de tabela em produção causados por queries pesadas de um domínio bloqueando operações de outro

    →  Qualquer mudança de schema virava uma operação de risco — ninguém sabia ao certo quem mais dependia daquelas colunas

    →  Impossível escalar um serviço de forma independente: o gargalo estava sempre no banco

    →  Índices criados para otimizar um serviço impactavam negativamente a performance de outro

    →  Incidentes em produção eram difíceis de isolar — tudo estava acoplado no mesmo ponto

    O banco compartilhado não era um detalhe técnico. Era uma bomba-relógio esperando o volume certo para explodir.

    Por que isso acontece — mesmo em times experientes

    Ninguém decide conscientemente criar um monolito de banco. O que acontece é que o sistema começa pequeno, com poucos serviços, e separar o banco "depois" sempre parece mais arriscado do que deixar como está.

    Cada sprint tem prioridades. A dívida técnica vai crescendo. E o argumento que mantém o problema vivo por anos é sempre o mesmo:

    "Separar agora vai quebrar tudo. Melhor deixar pra depois."

    Esse argumento tem uma base real. Uma migração mal planejada pode causar mais problemas do que resolve. Mas o ponto central é que a separação não precisa ser uma grande migração feita de uma vez. Ela precisa ser incremental.

    Como separar sem quebrar o que já existe: um processo em 5 etapas

    A diferença entre uma migração bem-sucedida e um desastre costuma estar na estratégia de execução — não na complexidade técnica. Veja o que funciona na prática:

    1.   Mapeie quem escreve em cada tabela

    Antes de mover qualquer dado, identifique os donos reais de cada tabela. Leitura compartilhada é tolerável no curto prazo. Escrita compartilhada é o problema — é ela que gera conflitos de schema, travamentos e os acoplamentos mais difíceis de desfazer. No nosso caso, o serviço de Averbação precisava de dados de Orders para gerar romaneios, mas escrevia na mesma tabela de entregas. Esse acoplamento de escrita foi um dos primeiros a ser isolado.

    2.   Comece pelo serviço mais isolado — não pelo mais crítico

    A primeira separação serve para validar o processo, não para resolver o maior problema. No contexto de uma plataforma logística, o serviço de Notificação costuma ser um bom candidato: ele consome dados de outros serviços, mas raramente é consumido por eles. Isolar esse banco primeiro permite que a equipe aprenda o fluxo de migração com risco baixo, antes de tocar em Orders ou Financeiro.

    3.   Aplique o padrão Strangler Fig no banco

    O mesmo padrão usado para migrar código legado funciona aqui. O novo serviço passa a ter seu próprio banco. Os dados que ele precisa de outros domínios chegam via evento ou via chamada de API — nunca via JOIN direto entre bancos.

    Na prática: quando o serviço de Averbação precisava dos dados de carga de uma entrega, em vez de fazer JOIN com a tabela de Orders, passamos a publicar um evento OrderDispatched com os dados necessários. O serviço de Averbação consumia esse evento e armazenava o que precisava no próprio banco — sem depender do banco de Orders para operar.

    4.   Elimine os JOINs entre domínios gradualmente

    Esse é o passo mais doloroso. JOINs entre tabelas de domínios diferentes geralmente indicam uma de duas situações:

    →  Você precisa desnormalizar e replicar o dado necessário no serviço que o consome

    →  A fronteira entre os serviços está mal definida e precisa ser repensada antes da separação técnica

    No caso do serviço Financeiro, havia JOINs com a tabela de Motoristas para calcular repasses. A solução foi o serviço Financeiro passar a manter uma projeção local dos dados de motorista que precisava — atualizada via eventos sempre que o cadastro mudava. Mais dados para gerenciar, sim. Mas sem o acoplamento que travava a operação.

    5.   Defina uma data de corte para duplicação temporária de dados

    Dados históricos às vezes precisam existir nos dois lugares por um período de transição. Isso é aceitável — desde que tenha prazo definido e monitoramento ativo. Sem prazo, duplicação temporária vira arquitetura permanente, e você criou um novo problema no lugar do antigo.

    O que muda depois que você separa

    Depois de isolar os primeiros serviços, alguns problemas simplesmente desaparecem:

    ✅ A query pesada do serviço de Orders não trava mais o Financeiro — são bancos separados

    ✅ Falha em um serviço não provoca efeito cascata nos outros

    ✅ Cada banco reflete apenas o domínio dele — sem colunas herdadas de contextos diferentes

    ✅ Deploy, escala e otimização passam a ser decisões independentes por serviço

    ✅ Schema deixa de ser um campo minado compartilhado entre times

    Atenção: separar o banco sem definir domínio é trocar um problema por outro

    Esse é o ponto que costuma ser ignorado. A separação técnica do banco resolve o sintoma — mas não necessariamente a causa.

    O banco compartilhado é o sintoma. Fronteira de domínio mal definida é a causa.

    Enquanto os times não tiverem clareza sobre quem é o dono de cada dado, o acoplamento vai reaparecer em outra camada: via chamadas síncronas excessivas entre serviços, via replicação inconsistente de dados, via eventos usados como substitutos de JOINs sem nenhuma consistência garantida. O problema muda de forma, mas não desaparece.

    Conclusão

    Separar banco em microsserviços não é uma tarefa técnica pontual. É um trabalho contínuo de definição de domínio, disciplina de equipe e migração incremental.

    Trabalhei num sistema onde esse problema era real, com volume real e consequências reais em produção. A separação não aconteceu de uma vez — aconteceu serviço por serviço, tabela por tabela, com aprendizado acumulado a cada etapa.

    A separação bem feita não é heroica. É incremental, documentada e feita com os domínios bem definidos antes de qualquer linha de código ser movida.

    Você já passou por uma migração assim? Como foi no seu contexto?

    Conta nos comentários — cada sistema tem suas particularidades, e a troca de experiência entre quem viveu isso na prática vale muito mais do que qualquer tutorial.

    https://www.linkedin.com/pulse/voc%C3%AA-tem-um-monolito-disfar%C3%A7ado-mateus-souza-yzphf/

    Compartilhe
    Recomendados para você
    AWS - Agentes de IA em Campo
    Michael Page - Criando Seu Primeiro Agente de IA
    Sem Parar Corpay - Back-end do Zero a Prática
    Comentários (0)