Trabalhei em alguns projetos em que a maior parte da lógica de negócios foi implementada no banco de dados (principalmente por meio de procedimentos armazenados). Por outro lado, ouvi de alguns colegas programadores que essa é uma prática ruim ("Os bancos de dados existem para armazenar dados. Os aplicativos existem para fazer o resto").
Qual dessas abordagens é geralmente a melhor?
Os profissionais da implementação da lógica de negócios no banco de dados em que posso pensar são:
- Centralização da lógica de negócios;
- Independência do tipo de aplicativo, linguagem de programação, SO, etc;
- Os bancos de dados são menos propensos a migração de tecnologia ou grandes refatorações (AFAIK);
- Sem retrabalho na migração da tecnologia de aplicativos (por exemplo: .NET para Java, Perl para Python, etc).
Os contras:
- O SQL é menos produtivo e mais complexo para a programação da lógica de negócios, devido à falta de bibliotecas e construções de linguagem que as linguagens mais orientadas a aplicativos oferecem;
- Reutilização de código mais difícil (se possível) através das bibliotecas;
- IDEs menos produtivos.
Nota: Os bancos de dados de que falo são bancos de dados relacionais e populares, como SQL Server, Oracle, MySql etc.
Obrigado!
Respostas:
A lógica de negócios não entra no banco de dados
Se estamos falando de aplicativos de várias camadas, parece bastante claro que a lógica de negócios, o tipo de inteligência que administra uma empresa específica, pertence à camada lógica de negócios, não à camada de acesso a dados.
Os bancos de dados fazem algumas coisas muito bem:
Agora, é claro, você pode codificar todos os tipos de coisas em um banco de dados que pertencem às suas preocupações comerciais, como taxas de impostos, descontos, códigos de operação, categorias e assim por diante. Mas a ação comercial executada nesses dados geralmente não é codificada no banco de dados, por todos os tipos de razões já mencionados por outros, embora uma ação possa ser escolhida no banco de dados e executada em outro local.
E, é claro, pode haver coisas que são executadas em um banco de dados por desempenho e outros motivos:
Naturalmente, nada está gravado em pedra. Os procedimentos armazenados são adequados para uma ampla variedade de tarefas, simplesmente porque residem no servidor de banco de dados e possuem certos pontos fortes e vantagens.
Procedimentos armazenados em todos os lugares
Existe um certo fascínio em codificar todas as suas tarefas de armazenamento, gerenciamento e recuperação de dados em procedimentos armazenados e simplesmente consumir os serviços de dados resultantes. Você certamente se beneficiaria com o máximo possível de otimizações de desempenho e segurança que o servidor de banco de dados poderia fornecer, e isso não é pouca coisa.
Mas o que você arrisca?
E, claro, se você precisar de um serviço da Web (que provavelmente é onde tudo está indo), você ainda precisará criar isso.
Então, o que é prática típica?
Eu diria que uma abordagem moderna e típica é usar um Mapeador Objeto-Relacional (como o Entity Framework) para criar classes que modelam suas tabelas. Você pode falar com seu banco de dados através de um repositório que retorna coleções de objetos, uma situação que é muito familiar para qualquer desenvolvedor de software competente. O ORM gera dinamicamente SQL correspondente ao seu modelo de dados e às informações solicitadas, que o servidor de banco de dados processa para retornar os resultados da consulta.
Quão bem isso funciona? Muito bem e muito mais rapidamente do que escrever procedimentos e visualizações armazenados. Isso geralmente cobre cerca de 80% dos requisitos de acesso a dados, principalmente CRUD. O que cobre os outros 20%? Você adivinhou: procedimentos armazenados, que todos os principais ORMs suportam diretamente.
Você pode escrever um gerador de código que faça o mesmo que um ORM, mas com procedimentos armazenados? Certamente você pode. Mas as ORMs geralmente são independentes do fornecedor, bem compreendidas por todos e têm melhor suporte.
fonte
Acredito firmemente em manter a lógica de negócios fora do banco de dados, tanto quanto possível. No entanto, como desenvolvedor de desempenho da minha empresa, compreendo que às vezes seja necessário obter um bom desempenho. Mas acho que é necessário com muito menos frequência do que as pessoas afirmam.
Eu discuto seus prós e contras.
Você alega que centraliza sua lógica de negócios. Pelo contrário, acho que o descentraliza. Em um produto em que trabalho atualmente, usamos o procedimento armazenado para grande parte da nossa lógica de negócios. Muitos de nossos problemas de desempenho vêm da chamada de funções repetidamente. Por exemplo
O problema dessa abordagem é que geralmente (em alguns casos, isso é falso) força o banco de dados a executar sua função N vezes, uma vez por linha. Às vezes, essa função é cara. Alguns bancos de dados suportam índices de função. Mas você não pode indexar todas as funções possíveis em relação a todas as entradas possíveis. Ou você pode?
Uma solução comum para o problema acima é extrair a lógica da função e mesclá-la na consulta. Agora você quebrou o encapsulamento e a lógica duplicada.
Outro problema que vejo é chamar procedimentos armazenados em um loop, porque não há como ingressar ou cruzar conjuntos de resultados de processos armazenados.
Se você extrair o código do processo aninhado, descentralizará novamente. Portanto, você é forçado a escolher entre encapsulamento e desempenho.
Em geral, acho que os bancos de dados são ruins em:
Os bancos de dados são bons em:
Ao realizar operações caras, como loops e análise de strings e mantê-las na camada do aplicativo, você pode dimensionar horizontalmente o aplicativo para obter um melhor desempenho. Adicionar vários servidores de aplicativos atrás de um balanceador de carga geralmente é muito mais barato do que configurar a replicação de banco de dados.
Você está correto, no entanto, que desacopla sua lógica de negócios da linguagem de programação de seu aplicativo, mas não vejo por que isso é uma vantagem. Se você possui um aplicativo Java, possui um aplicativo Java. A conversão de vários códigos Java em procedimentos armazenados não altera o fato de você ter um aplicativo Java.
Minha preferência é manter o código do banco de dados focado na persistência. Como você cria um novo widget? Você deve inserir em 3 tabelas e elas devem estar em uma transação. Isso pertence a um procedimento armazenado.
A definição do que pode ser feito com um widget e as regras de negócios para localizar widgets pertencem ao seu aplicativo.
fonte
Trabalhei em 2 empresas diferentes que tinham uma visão diferente sobre o assunto.
Minha sugestão pessoal seria usar procedimentos armazenados quando o tempo de execução for importante (desempenho). Como o Stored Procedure é compilado, se você tiver uma lógica complexa para consultar os dados, é melhor mantê-lo no próprio banco de dados. Além disso, ele enviará apenas os dados finais para o seu programa no final.
Caso contrário, acho que a lógica de um programa deve sempre estar no próprio software. Por quê? Como um programa precisa ser testável e não acho que exista uma maneira fácil de testar o procedimento armazenado da unidade. Não se esqueça, um programa que não foi testado é um programa ruim.
Portanto, use o procedimento armazenado com cuidado, quando necessário.
fonte
Há um meio termo que você precisa encontrar. Vi projetos assustadores em que os programadores usam o banco de dados como nada além de um armazenamento de chave / valor muito caro. Já vi outros em que os programadores falham em usar chaves e índices estrangeiros. No outro extremo do espectro, vi projetos em que a maioria, se não toda a lógica de negócios, é implementada no código do banco de dados.
Como você observou, o T-SQL (ou seu equivalente em outros RDBMSs populares) não é exatamente o melhor lugar para codificar lógica de negócios complexa.
Tento criar um modelo de dados razoavelmente decente, usar recursos do banco de dados para proteger minhas suposições sobre esse modelo (ou seja, FKs e restrições) e usar o código do banco de dados com moderação. O código do banco de dados é útil quando você precisa de algo (ou seja, uma soma) que o banco de dados seja muito bom em fazer e pode evitar que você mova um zilhão de registros pela rede quando não precisar deles.
fonte
Se sua lógica de negócios envolve operações de conjunto, provavelmente é um bom lugar para ele no banco de dados, porque os sistemas de banco de dados são realmente bons em executar operações de conjunto.
http://en.wikipedia.org/wiki/Set_operations_(SQL)
Se a lógica de negócios envolver algum tipo de cálculo, provavelmente ela estará fora do procedimento de banco de dados / armazenamento, pois os bancos de dados não são realmente projetados para loop e cálculo.
Embora essas regras não sejam difíceis e rápidas, é um bom ponto de partida.
fonte
Não existe uma resposta certa para isso. Depende do que você usa o banco de dados. Em um aplicativo corporativo, você precisa da lógica no banco de dados através de chaves estrangeiras, restrições, gatilhos etc. porque é o único local em que todos os aplicativos possíveis compartilham código. Além disso, colocar a lógica necessária no código geralmente significa que o banco de dados é inconsistente e os dados são de baixa qualidade. Isso pode parecer trivial para um desenvolvedor de aplicativos que apenas concorda com o funcionamento da GUI, mas garanto que as pessoas que tentam usar os dados nos relatórios de conformidade acham muito irritante e dispendioso quando recebem multas de bilhões de dólares por terem dados que não siga as regras corretamente.
Em um ambiente não regulatório, quando você não se importa tanto com todo o conjunto de registros e apenas um ou dois aplicativos atingem o banco de dados, talvez você consiga manter tudo no aplicativo.
fonte
Depois de alguns anos, a questão ainda é importante ...
Uma regra prática simples para mim: se for uma restrição lógica ou uma expressão onipresente (instrução única), coloque-a no banco de dados (sim, chaves estrangeiras e restrições de verificação também são lógicas de negócios!). Se for processual, contendo loops e ramificações condicionais (e realmente não pode ser transformado em uma expressão), coloque-o no código.
Evitar DBs de despejo de lixo
Tentativas de colocar realmente toda a lógica de negócios no código do aplicativo provavelmente degenerarão o banco de dados (relacional) em um lixeira, onde o design relacional é quase totalmente omitido, onde os dados podem ter qualquer estado inconsistente e a normalização está ausente (geralmente XML, JSON , CSV etc. colunas da lixeira).
Esse tipo de lógica somente de aplicativo é provavelmente uma das principais razões para o surgimento do NoSQL - é claro, com a desvantagem de que o aplicativo precisa cuidar de toda a lógica em si, o que foi incorporado ao DB relacional por décadas. No entanto, os bancos de dados NoSQL são mais adequados para esse tipo de manipulação de dados, por exemplo, documentos de dados mantêm uma "integridade relacional" implícita dentro de si. Para bancos de dados relacionais, é simplesmente abuso, causando ainda mais problemas.
Expressões (baseadas em conjunto) em vez de código processual
Na melhor das hipóteses, toda consulta ou operação de dados deve ser codificada como uma expressão, em vez de código processual. Um ótimo suporte para isso é quando as linguagens de programação suportam expressões, como LINQ no mundo .NET (infelizmente, apenas consultas atualmente, sem manipulação). No lado do banco de dados relacional, foi ensinado por um longo tempo a preferir expressões de instrução SQL em vez de loops de cursor procedurais. Portanto, o banco de dados pode otimizar, executar a operação em paralelo ou o que for útil.
Utilize mecanismos de integridade de dados de banco de dados
Quando se trata de RDBMS com restrições de Chave estrangeira e verificação, colunas calculadas, possivelmente gatilhos e visualizações, este é o local para armazenar a lógica comercial básica no banco de dados. A normalização adequada ajuda a manter a integridade dos dados, para garantir uma instância única e distinta dos dados. Mesmo se você precisar duplicá-lo no código e no banco de dados, esses mecanismos básicos de integridade dos dados não devem ser omitidos!
Procedimentos armazenados?
Atualmente, os procedimentos armazenados raramente são necessários, pois os bancos de dados mantêm planos de execução compilados para SQL e os reutilizam quando a mesma consulta volta, apenas com parâmetros diferentes. Portanto, o argumento de pré-compilação para SPs não é mais válido. Pode-se armazenar ou gerar automaticamente consultas SQL no aplicativo ou ORM, que encontrará planos de consulta pré-compilados na maioria das vezes. SQL é uma linguagem de expressão, desde que você não use explicitamente elementos procedimentais. Portanto, na melhor das hipóteses, você usa expressões de código que podem ser traduzidas para SQL.
Enquanto o lado do aplicativo, incluindo o ORM gerado, SQL, não está mais dentro do banco de dados, ao contrário dos Procedimentos Armazenados, continuo contando-o como código do banco de dados. Como ainda requer conhecimento de SQL e banco de dados (exceto o CRUD mais simples) e, se aplicado corretamente, funciona muito diferente do código de procedimento geralmente criado com linguagens de programação como C # ou Java.
fonte
Realmente depende do negócio, sua cultura e legado. Além de considerações técnicas (estas foram abordadas pelos dois lados), as respostas dadas dizem que se trata de onde as pessoas vêm. Em algumas organizações, os dados são o rei e o DBA é uma figura poderosa. Este é o seu ambiente centralizado típico, um data center com vários terminais conectados a ele. A preferência neste tipo de ambiente é clara. A área de trabalho pode mudar radicalmente várias vezes antes que algo mude no data center e haverá pouco tempo entre elas.
A outra extremidade do espectro é a arquitetura pura de três camadas. Ou talvez multicamada em um negócio orientado para a Web. Você provavelmente ouvirá uma história diferente aqui. O DBA, se houver, será apenas um ajudante que executa algumas tarefas administrativas.
Um desenvolvedor de aplicativos dos tempos modernos terá mais afinidade com o segundo modelo. Se você cresceu com um grande sistema cliente-servidor, provavelmente estaria no outro campo.
Muitas vezes há muitos fatores não técnicos relacionados ao ambiente envolvidos aqui, não há resposta geral para essa pergunta.
fonte
O termo lógica de negócios está aberto à interpretação. Ao construir sistemas, queremos garantir a integridade do banco de dados e seu conteúdo. Como primeira etapa, deve haver diferentes concessões de acesso de usuários. Como um exemplo muito simples, vamos considerar um aplicativo ATM.
Para obter o saldo da conta, fazer uma seleção em uma exibição apropriada deve funcionar. Mas, para transferir fundos, você deseja que a transação seja encapsulada por um procedimento armazenado. A lógica de negócios não deve ter permissão para atualizar diretamente as tabelas dos valores de crédito e débito.
Neste exemplo, a lógica de negócios pode verificar o saldo antes de solicitar a transferência ou simplesmente chamar o processo armazenado para a transferência e relatar a falha. IMHO, a lógica de negócios, neste exemplo, deve verificar preventivamente se há fundos suficientes disponíveis e se a conta de destino existe e somente então invocar os fundos de transferência. Se outro débito ocorrer entre as etapas iniciais e a chamada do procedimento armazenado, somente um erro será retornado.
fonte