Todo desenvolvedor que tenha um conhecimento razoável sobre banco de dados já passou pela dúvida sobre como lidar com a possibilidade de concentrar boa parte das regras de negócio dentro do banco de dados.
Atualmente, com a disponibilidade de várias linguagens de programação, isto se torna cada vez mais tentador: a Oracle possui além do consagrado PL/SQL, suporte a Java, o PostgreSQL chegou num estado de arte suportando uma infinidade de linguagens de programação dentro de seu SGDB e agora já faz um ano que o MySQL também possui sua própria implementação de linguagem procedural.
Mas o uso desgovernado deste tipo de expediente pode trazer algumas desvantagens. Longe de querer ditar melhores práticas, gostaria aqui de discutir um pouco este tema que tem me intrigado por algum tempo.
Nos primórdios da informática, onde reinavam solenes apenas os computadores de grande porte, não havia a opção de distribuir a carga de processamento em várias máquinas separadas. Os SGDBs relacionais também começaram a nascer somente no final da década de 70 com o DB2, Oracle e Ingres. Sendo assim, toda a aplicação se concentrava em geral na mesma máquina.
Com o surgimento dos microcomputadores veio a revolução da arquitetura cliente-servidor no final da década de 80. A idéia era criar aplicações rodando em microcomputadores (clientes) e armazenar as informações em SGDBs que ficassem em máquinas mais confiáveis (servidores). Com isso foi possível adquirir servidores com um preço bem mais acessível que os computadores de grande porte, uma vez que a carga de processamento da aplicação ficou distribuída nos microcomputadores dos usuários.
Nesta época, linguagens como o VB e o Delphi invadiram o mercado construindo aplicações cliente servidor com pães numa padaria. As aplicações cliente-servidor em boa parte foram muito bem sucedida, mas em ambientes corporativos elas começaram a apresentar uma performance muito insatisfatória. Conforme o tamanho do código cresce e as aplicações vão ficando mais pesadas várias coisas acontecem:
- O código fica difícil de manter (bem, isto não é nenhuma novidade…)
- Em transações longas, onde muito cálculo é utilizado, as máquinas utilizadas no cliente tem baixa capacidade de processamento, tornando a operação lenta.
- Em transações longas com várias consultas ao banco de dados, o tráfego de rede é muito alto e gera um gargalo de desempenho.
- Pequenas falhas na rede durante o processamento de transações longas podem no mínimo obrigar toda a operação a ser reiniciada.
É neste ponto em que entra em cena a linguagem procedural embutida no banco de dados. Com isso, é possível disparar gatilhos em circunstâncias determinadas e executar procedures e funções dentro do SGDB. O ganho de velocidade em aplicações cliente-servidor é realmente fantástico em transações longas.
Mas como tudo na vida , algumas pessoas se empolgaram! A idéia destas pessoas foi a de utilizar as aplicações no cliente apenas para exibir e receber informações, deixando todo o processamento das informações dentro do SGDB. Uma vantagem interessante desta técnica ocorre quando você possui mais de uma aplicação acessando o mesmo banco de dados. Um exemplo disto poderia ser uma aplicação cliente-servidor tradicional utilizada para alimentar e processar as informações, uma planilha extraindo informações complexas do banco de dados e uma aplicação web fazendo consultas de informações específicas. Neste ponto, centralizar toda a “inteligência” ou “regras de negócio” dentro do SGDB facilita a vida de quem tem que manter o código destas diferentes aplicações.
E qual a desvantagem disto? Bem, os ajustes de desempenho do SGDB tem que mudar drasticamente. Antes a coisa mais importante no desempenho de um banco de dados transacional era a velocidade dos seus discos. Com o acúmulo de tarefas de processamento da aplicação dentro do SGDB na mesma máquina o processador começa a assumir um papel cada vez mais importante. O resultado disto pode ser um SGDB muito lento.
Enquanto isto novas tendências de mercado começaram a ganhar força: Programação Orientada a Objeto e Aplicações Web. Na programação orientada a objeto, as linguagens procedurais perdem seu papel, pois estão muito mais próxima da lógica relacional dos SGDBs, embora o Sr. C. J. Date afirme que a maior parte dos fundamentos da P.O.O. estão na teoria relacional. Seja como for, outra tendência que ganhou força com a orientação a objetos é a programação em camadas. Com isso, o aplicativo começa a ser dividido em unidades funcionais, sendo que algumas delas certamente ficarão a cargo de servidores dedicados com maior capacidade de processamento, e conexão de rede dedicada com o SGDB. O mesmo acontece naturalmente em aplicações Web onde o processamento não é realizado em um computador cliente e sim no servidor web (ou em mais servidores se a aplicação for realizada em várias camadas).
Hoje se fala muito em camadas de abstração de bancos de dados e em frameworks MVC. Eles permitem que você desenvolva a aplicação sem se preocupar com qual banco de dados está utilizando. Desta forma, as linguagens procedurais nos SGDBs perderiam completamente sua função! A idéia é realmente tentadora.
No entanto, quando estudamos as boas opções no mercado, verifica-se a existência de brechas para enviar comandos específicos para cada SGDB. Isto ocorre porque se a abstração de SGDB fosse perfeita, certamente não precisaríamos de diferentes SGDBs no mercado. Há momentos em que é preciso acessar funcionalidades específicas de cada SGDB que as camadas de abstração não são capazes de lidar diretamente. Quando se precisa de funcionalidades avançadas e/ou alto desempenho em longas transações, as linguagem procedurais ainda são utilizadas mesmo em aplicações com várias camadas como no modelo MVC.
É claro que as camadas de abstração de dados tendem a evoluir, assim como o padrão SQL tem evoluído. No entanto estamos longe de uma padronização das linguagens procedurais dentro de bancos de dados, além de haverem novas funcionalidades sendo implementadas todos os dias nos SGDBs relacionais. Dito isto, é provável que aplicações continuem se beneficiando de camadas de abstração de dados, no entanto elas não cobrirão plenamente as necessidades de grandes aplicações corporativas, devendo haver sempre brechas para acessar diretamente as funcionalidades especificas de cada SGDB.
Enfim não existe uma regra clara para utilização de linguagens procedurais dem SGDBs. Existem funcionalidades como prover auditabilidade, gerar logs e realizar a carga de dados complexos onde estes são consagrados, além do processamento de longas transações com velocidade e confiabilidade ainda imbatíveis.
Em sistemas pequenos, a centralização da inteligência da aplicação dentro de SGDBs é aceitável, porém com o aumento de aplicações Web e frameworks como o Ruby On Rails, esta não parece ser uma tendência de longo prazo.
Por fim, este assunto é bastante polêmico e não existem regras formais para o uso de linguagens procedurais em SGDBs. A criatividade e o bom censo dos desenvolvedores e DBAs podem sempre apontar para novos rumos ou demonstrar equívocos.
Se você tem uma opinião diferente ou quer acrescentar alguma coisa, deixe seu comentário abaixo.