De SQL para NoSQL: por que e como migramos nosso app sem morrer na tentativa
Quando você começa a desenvolver um app, é natural se apoiar no que conhece bem. Para nós, o SQL era “a velha confiável”. Sua estrutura robusta e familiar nos dava segurança para avançar rápido nas primeiras etapas. Quem não ama um bom banco de dados relacional, com relacionamentos perfeitamente organizados e aquelas consultas complexas que fazem você se sentir um mestre Jedi dos dados?
Só que, à medida que a aplicação cresce e evolui, essa mesma rigidez e estrutura que antes era uma vantagem vai virando uma limitação. Foi assim que “a velha confiável” passou a nos dar mais dor de cabeça do que tranquilidade.
A decisão de migrar
Nosso app tinha crescido e mudado bastante desde o nascimento. O modelo de dados tinha virado um monstro difícil de administrar. Criamos tabelas intermediárias para coisas pequenas, começamos a usar jsonb para armazenar dados que não cabiam nas estruturas tradicionais e a excluir registros sob condições específicas que acrescentavam mais complexidade do que o necessário.
Percebemos que estávamos forçando nosso banco de dados relacional além dos seus limites naturais.
Foi aí que apareceu o MongoDB como solução. Essa mudança para NoSQL nos trazia vantagens que o SQL simplesmente não podia oferecer:
Esquemas flexíveis: podíamos adicionar ou remover campos sem ter que redesenhar toda a estrutura do banco de dados.
Consultas mais simples: algumas operações eram muito mais intuitivas no MongoDB do que no SQL.
Escalabilidade horizontal: conforme crescêssemos, poderíamos distribuir os dados entre vários servidores com mais facilidade.
O problema estava claro: o SQL já não era o que precisávamos para o futuro do nosso app.
Simplificando a complexidade
Nosso antigo diagrama entidade-relacionamento (DER) em SQL tinha virado um verdadeiro labirinto. Cada nova funcionalidade exigia mais tabelas, mais relacionamentos, mais joins. Tentar entender como todas aquelas tabelinhas funcionavam era quase como ficar depurando bugs o tempo todo, só que sem nenhum erro de código de verdade.
Nosso diagrama em SQL era mais ou menos assim:
Depois de uma boa quantidade de sessões de modelagem, conseguimos simplificar nosso esquema de dados e reduzir o número de "tabelas" em mais de 50%. O resultado foi um modelo mais claro, mais eficiente e muito mais fácil de administrar.
Assim ficou o novo diagrama com MongoDB:
O impacto
Essa nova estrutura nos permitiu:
Consultas mais rápidas: obter os detalhes de uma validação agora é questão de buscar um único documento.
Código mais limpo: nos livramos do labirinto de relacionamentos complexos.
Mais flexibilidade: adicionar ou remover atributos é tão fácil quanto modificar um documento, sem precisar de migrações. Podemos até aninhar documentos inteiros dentro de outros.
Como tudo na vida, isso também tem suas desvantagens.
Se não formos cuidadosos, a flexibilidade do MongoDB pode introduzir inconsistências ou erros difíceis de detectar. Mas aprendemos a lidar com esses desafios:
Controle da flexibilidade: usamos tipagem de documentos para evitar inconsistências.
Consultas otimizadas: implementamos índices para melhorar o desempenho de algumas buscas frequentes.
Tratamento de inconsistências: criamos migrações de dados para campos que perderam o formato durante a migração.
Como migrar de SQL para MongoDB
Se você já teve que migrar um banco de dados em produção, sabe que não é algo que se queira fazer numa sexta à tarde. É um processo complexo, no qual muita coisa pode dar errado:
Existe o risco de alguns dados não serem migrados ou se corromperem durante a transferência.
Um planejamento ruim ou um tempo de migração mal calculado pode deixar a aplicação fora do ar e afetar os usuários.
Mudar a estrutura do banco de dados pode quebrar as consultas existentes, já que os relacionamentos e os esquemas mudam significativamente
Mesmo assim, conseguimos, e nosso app não parou de funcionar em nenhum momento.
Aqui eu conto como fizemos, passo a passo:
1. Preparação e testes
Desenvolvemos e testamos scripts para migrar os dados do PostgreSQL para o MongoDB. Testamos, ajustamos e testamos de novo para ter certeza absoluta.
2. Primeira migração:
Movemos todos os dados existentes para o MongoDB, mas continuamos operando com o PostgreSQL. Durante alguns minutos, nosso app viveu em um estado de Schrödinger, coexistindo em SQL e NoSQL.
3. O grande switch:
Mudamos o código para que o Mongoid substituísse o ActiveRecord e, a partir daquele momento, nosso app começou a trabalhar com o MongoDB.
4. Segunda migração:
Logo depois do switch, migramos de novo para capturar qualquer dado novo gerado entre a primeira migração e a virada.
5. Verificação e ajustes:
Conferimos se tudo estava funcionando bem. Último passo: respirar aliviados e comemorar.
Esse processo nos permitiu fazer uma migração sem tempo de inatividade e sem perda de dados. Foi como trocar as rodas de um carro em movimento.
Depois da migração
Meses depois, não temos dúvidas: foi a decisão certa. Reduzimos os bugs, simplificamos as consultas e o tempo que levamos para mudar o modelo de dados caiu bastante.
Antes, por exemplo, modificar a estrutura de uma tabela no SQL exigia migrações complexas e coordenadas. Agora, com o MongoDB, adicionar um novo campo a um documento é tão simples quanto incluí-lo em uma atualização. E as consultas que antes exigiam vários joins hoje se resolvem com uma única busca em um documento aninhado.
Migrar de SQL para NoSQL não foi fácil, mas o resultado é um sistema mais ágil, flexível e escalável.
Se você está pensando em fazer uma mudança parecida, avalie suas necessidades, planeje bem e não tenha medo de se adaptar. No fim, o esforço vale a pena.
E, embora o SQL sempre vá ser “a velha confiável”, às vezes o melhor é abraçar o novo.