Quais são os argumentos contra ou para colocar a lógica do aplicativo na camada do banco de dados?

74

OBSERVAÇÃO O público de programmers.se e dba.se é diferente e terá pontos de vista diferentes; portanto, neste caso, acho válido duplicar Quais são os argumentos contra ou para colocar a lógica do aplicativo na camada do banco de dados? em programmers.se.

Eu não consegui encontrar discussão sobre o dba sobre isso já, e o post original diz tudo, então:

A maioria dos desenvolvedores de software deseja manter a lógica do aplicativo na camada de aplicativos e provavelmente parece natural mantê-lo aqui. Os desenvolvedores de banco de dados parecem querer colocar a lógica do aplicativo na camada do banco de dados, como gatilhos e procedimentos armazenados.

Pessoalmente, eu preferiria manter o máximo possível na camada do aplicativo para facilitar a depuração e manter as responsabilidades das camadas separadas.

O que você pensa sobre isso e o que deve ou não ser aprovado para implementar na camada de banco de dados?

NB: Não sou o OP dessa pergunta, mas deixei o texto original intacto.

Phil Lello
fonte
4
Comparando as respostas aqui e no SO, a diferença é impressionante. Os desenvolvedores protestam contra os atrasos decorrentes dos processos de centralização no banco de dados, mas para os DBAs isso é uma coisa boa. Forçar as pessoas a dedicar mais tempo e esforço ao solicitar uma nova visualização ou sproc reduz o número de pontos de contato com os dados, facilitando a manutenção da consistência e reduzindo o número de pontos de otimização.
Jon of All Trades
Parece-me que as respostas aqui assumem uma certa maneira de usar o banco de dados (vários aplicativos, permitindo a alguns usuários o acesso direto ao banco de dados, etc.). Acho que esse é o principal motivo da diferença.
JMD Coalesce

Respostas:

56

Pensamentos variados ...

O código do banco de dados sobreviverá à tecnologia do cliente do aplicativo. Pense no ADO.NET -> Linq -> EF, bem como em ORMs variados. Considerando que você ainda pode executar o código do SQL Server 2000 do último milênio em todas as tecnologias de cliente acima.

Você também tem o problema de vários clientes: eu tenho .net, java e Excel. São 3 conjuntos de lógica de aplicação.

"Lógica comercial" não deve ser confundida com "lógica de integridade de dados". Se você tem clientes iniciando transações e fazendo verificações variadas, são muitas chamadas de banco de dados e uma transação longa.

A lógica do aplicativo não é dimensionada para grandes volumes de dados. Temos 50 mil linhas por segundo usando procs armazenados. Uma equipe irmã que usa o Hibernate não consegue um por segundo

gbn
fonte
Enquanto você ficar com bancos de dados relacionais
JMD Coalesça
1
@JMDCoalesce: Você ainda precisa de lógica de negócios e é capaz de ter vários aplicativos clientes. Qual é o seu ponto?
gbn
40

Eu quero toda a lógica que deve ser aplicada a todos os usuários e todos os aplicativos no banco de dados. Esse é o único lugar sensato para colocá-lo.

As últimas Fortune 500 em que trabalhei tinham aplicativos escritos em pelo menos 25 idiomas, atingindo seu banco de dados OLTP. Alguns desses programas foram movidos para produção na década de 1970.

A alternativa para implementar esse tipo de requisito no banco de dados é permitir que todos os programadores de aplicativos reimplementem tudo ou parte dele 100% corretamente, toda vez que acionam seu editor, desde o primeiro momento em que entram pela porta até a empresa sair o negócio.

Quais são as hipóteses?

Não é este o maior " não se repita " no planeta?

Mike Sherrill 'Rechamada de gato'
fonte
Isso só se aplica se vários aplicativos usar um banco de dados
JMD Coalesça
1
@JMDCoalesce, que é comum em muitos ambientes. Aplicativo principal, relatórios do Excel, relatórios do lado do servidor, extrações em massa: em breve será adicionado. Quase qualquer aplicação bancária tem uma infinidade de aplicativos cliente,
GBN
Claro, mas nem todos os aplicativos são para serviços bancários.
JMD Coalesce
29

Estou movendo minha antiga resposta através do programmers.se não editada, pois as respostas parecem bastante polarizadas entre os sites.

Sei que estou em um mundo de mágoas aqui, mas coloquei a lógica de negócios no banco de dados porque:

  • Você pode permitir que os usuários avançados de negócios acessem diretamente o banco de dados e não se preocupe com eles estragando tudo (ou se preocupe menos do que você faria com a lógica baseada em aplicativo)
  • Um usuário avançado pode criar novos relatórios sem aguardar uma nova versão do software.
  • Você pode testar o código SP / TRIGGER em uma cópia do banco de dados, assim como faz o teste da lógica baseada em aplicativo
  • Você pode manter o SQL para criar sps e triggers em arquivos de texto (você deve fazer isso de qualquer maneira para código de tabela / exibição)
  • Você pode misturar e combinar idiomas sem portar lógica de negócios
  • Você pode fazer alterações na lógica de negócios sem atualizar todos os bits de software
  • Você audita as alterações na estrutura da mesma maneira que audita a atividade do banco de dados - via log
  • Segurança e controle de acesso detalhados amplamente aprimorados (a maioria das implementações lógicas baseadas em aplicativos usa seu próprio modelo de segurança, para que os dados sejam muito mais fáceis de comprometer. A criptografia reversível de senha não é incomum)
  • A segurança do usuário do lado do banco de dados reduz bastante o dano / roubo do SQL desonesto

Os contras são: - Desenvolvedores ameaçados quando os usuários se tornam menos dependentes de desenvolvedores para relatórios personalizados - Desenvolvedores precisam aprender outra linguagem de programação

Nenhum desses deve ser importante para um desenvolvedor qualificado.

Interessante notar, a maioria das respostas fala em termos de 'lógica de aplicativo', não de 'lógica de negócios', como se o software não estivesse lá para fornecer uma função de negócios.

Phil Lello
fonte
1
* Procs / triggers armazenados podem fornecer um nível de abstração que permite fazer alterações estruturais no banco de dados sem precisar alterar todo o código do aplicativo. * Nem todo usuário do banco de dados usará fielmente seu middleware. * Vamos lá, uma chave estrangeira é uma regra de negócios !! * Remover todas as verificações / restrições / código do banco de dados significa que ele não pode se proteger contra inconsistências / corrupção. * Todo aplicativo não exige designs sem transações orientados a filas, como o que o eBay desenvolveu depois de se tornar bem-sucedido e poderia se dar ao luxo de criar isso. * SQL não é tão difícil, pessoal.
Craig
23

A questão mais importante é se alguma 'camada' acima do banco de dados pensa que possui os dados. Simultaneidade e integridade dos dados são problemas para os quais a solução é um RDBMS - alguns aplicativos são desenvolvidos como se o banco de dados fosse apenas um depósito de bits pessoal e, é claro, eles acabam tentando reinventar a roda de várias maneiras, bem como sendo irreparavelmente quebrado assim que outro aplicativo acessar o mesmo banco de dados

Jack Douglas
fonte
1
Eu acho que quem patrocina o sistema possui os dados - eles pagaram por isso. Também resolvo muitos problemas de simultaneidade antes que eles atingissem o banco de dados - em muitos casos, é muito mais fácil.
AK
4
você está usando 'own' em um sentido diferente do que eu: o meu argumento é que, se você 'resolver' problemas de concorrência antes que eles atinjam o banco de dados, você também deverá garantir que os seus são os únicos aplicativos que atingem o banco de dados ou que precisam ser resolvidos tudo de novo naquele nível. Concordo com a resposta mais votada: "Seu código do banco de dados [provavelmente] sobreviverá à sua tecnologia de cliente de aplicativo".
Jack Douglas
17

Eu escrevi minha resposta para isso no meu blog . Minha conclusão é que fazê-lo no aplicativo simplesmente não aumenta quando você considera todo o ciclo de vida do aplicativo.


3. Adicione restrições de integridade / verificação ao banco de dados subjacente,com código mais complexo implementado na linguagem de procedimento armazenado do banco de dados. A partir disso, temos um local central para manter e temos uma aplicação absoluta das regras, mesmo para aplicativos que não conhecemos! Temos um idioma para expressar as regras de negócios, em todo o portfólio e ciclo de vida de aplicativos, uma vez que o idioma do dia muda muito mais frequentemente do que o banco de dados. E roda em um sistema que já é tão crítico quanto as aplicações mais importantes. Os erros são manipulados pelo código existente que lida com erros de banco de dados nesses aplicativos. Ainda existe o risco de um aplicativo quebrar, é claro, mas dos três cenários é o mínimo e apenas o aplicativo quebrado precisa de qualquer modificação, nem todos eles (e a maioria dos mecanismos de SP / banco de dados permitirá que uma exceção seja feita para um aplicativo, se isso for realmente necessário). Acha que isso não importa no seu site greenfield ou pequena empresa? Bem, se o seu negócio for bem-sucedido, em 30 anos você desejará ter prestado atenção à minha sabedoria!

… Algumas [objeções] eu sempre ouço:

  • É difícil controlar o código do SP implantado no banco de dados. Eu não acho que seja mais verdadeiro do que dizer que é difícil controlar o código Java implementado em um servidor de aplicativos, ou seja, não é difícil, é comum. E no Ruby-land, livros inteiros são escritos sobre como colocar seu código de um ambiente de desenvolvimento em produção, algo com o qual nenhuma outra comunidade de idiomas parece ter dificuldades. No entanto, a versão que controla um procedimento armazenado é aparentemente muito difícil.
  • Procedimentos armazenados são difíceis de testar. Este é um estranho. Para começar, os SPs são fortemente tipados; o compilador dirá se existe ou não um caminho de código que não faz sentido e, pelo menos no Oracle, calculará todas as dependências para você. Portanto, esse é um conjunto de testes de unidade comuns que você pode precisar no Ruby eliminado imediatamente. Para testar o código OO, é necessário zombar para coagir o objeto ao estado interno necessário para representar o cenário de teste - como a configuração dos dados de teste é diferente? Além disso, existe um produtor TAP para PL / SQL e outras ferramentas. Existem depuradores e criadores de perfil também.
  • Um idioma de procedimento armazenado não é um idioma completo. Bem, não estamos tentando escrever um aplicativo inteiro apenas em procedimentos armazenados! A maioria das linguagens SP dedicadas tem todas as construções modernas que você esperaria, e no Oracle, pelo menos, você pode usar Java Stored Procedures com todos os recursos de linguagem que os desenvolvedores OO estão familiarizados ou com procedimentos externos em qualquer idioma. O que importa é onde a lógica é implementada - em um local, próximo aos dados - a linguagem real é apenas um detalhe. PL / SQL compila para código nativo e é executado em processo com o banco de dados; não há arquitetura de desempenho superior a isso.
  • Eu não quero ter que aprender outro idioma. Negligenciar por um segundo isso é uma enorme bandeira vermelha em qualquer desenvolvedor (especialmente um que propõe modificar aplicativos de produção que podem estar em outros idiomas de qualquer maneira!), Há muito a aprender a trabalhar em qualquer ambiente moderno: uma loja Java típica pode ter Eclipse , WebLogic, Maven, Hudson, Anthill, Subversion e muitos outros, que você precisa aprender antes de escrever uma única linha de código de aplicativo. Um conhecimento prático de uma linguagem SP de nível muito alto é direto em comparação, e provavelmente haverá um especialista ou um DBA para ajudá-lo também. Sem mencionar que o Hibernate favorito do desenvolvedor vem com sua própria linguagem de consulta…

...

Gaius
fonte
12

O SQL faz coisas como definir lógica e filtragem de resultados orientada a aplicativos? SQL é uma maravilhosa linguagem de manipulação de conjuntos.

Além disso, como o GBN apontou acima, o código SQL sobreviverá quase universalmente ao código do aplicativo.

Embora seja verdade que EF ou NHibernate ou LinqToSql ou o que quer que permita gerar código mais rapidamente, todo programador que se preze sabe que apenas a otimização do SQL otimiza a recuperação de dados. O RDBMS entende apenas SQL, então você precisa transformar tudo em SQL antes que tudo seja dito e feito. (supondo que possamos concordar que TSQL e PLSQL ainda são SQL)

jcolebrand
fonte
11

Um golpe que as pessoas não estão necessariamente discutindo - os profissionais estão exaustos aqui - é o custo.

As CPUs no servidor de banco de dados são frequentemente as CPUs mais caras em qualquer organização, ao reduzir o custo da licença de software. Portanto, mover a lógica de negócios para a camada de dados é algo que deve ser feito criteriosamente, não necessariamente uniformemente.

Adam Musch
fonte
7

É aqui que o encontro das mentes, ou seja, as mentes dos desenvolvedores (DVs) e DBAs, deve inevitavelmente acontecer. Trabalhar com Business Logic (BL) e armazená-lo em um banco de dados pode ter um impacto que pode glorificar ou horrorizar sua implementação.

Para alguns produtos RDBMS, existem bibliotecas / ferramentas / APIs superiores para lógica de negócios e infraestruturas de objetos que se pode aprender e empregar rapidamente em seus aplicativos. Para outros RDBMS, não existem bibliotecas / ferramentas / APIs.

No passado, os aplicativos de servidor do cliente transformavam o BL em procedimentos armazenados (SP). Para produtos como Oracle e SQL Server, isso foi feito mais cedo. Quando surgiram os bancos de dados de código aberto, como PostgreSQL e MySQL, aqueles que os utilizavam corriam o risco de abrir novos caminhos com procedimentos armazenados no BL. O PostgreSQL amadureceu rapidamente, pois não apenas os procedimentos armazenados foram implementados, mas também a capacidade de criar as linguagens dos clientes. O MySQL basicamente parou de evoluir no mundo dos procedimentos armazenados e veio em uma forma simplificada de uma linguagem com muitas restrições. Portanto, quando se trata de BL, você está completamente à mercê do MySQL e da linguagem Stored Procedure.

Resta apenas uma pergunta: independentemente do RDBMS, o BL deve residir no todo ou em parte no banco de dados?

Pense no desenvolvedor. Quando as coisas dão errado em um aplicativo, o processo de depuração fará com que o Desenvolvedor entre e saia de um banco de dados para seguir as alterações de dados que podem ou não estar corretas de forma intermitente. É como codificar um aplicativo C ++ e chamar o código Assembler no meio. Você precisa mudar do código fonte, classes e estruturas para interrupções, registros e compensações E VOLTAR !!! Isso leva a depuração para o mesmo nível.

Os desenvolvedores podem criar um método de alta velocidade de execução de BL em conjunto com configurações de linguagem (sinalizadores de compilador para C ++, configurações diferentes para PHP / Python, etc.) por meio de objetos de negócios que ficam na memória e não em um banco de dados. Alguns tentaram conectar essa ideologia a códigos de execução mais rápidos no banco de dados, escrevendo bibliotecas em que a depuração de Procedimentos armazenados e gatilhos está bem integrada no banco de dados e aparentemente utilizável.

Assim, o desenvolvedor é desafiado a desenvolver, depurar e manter o código-fonte e o BL em dois idiomas.

Agora pense no DBA. O DBA deseja manter o banco de dados enxuto e significar o máximo possível no domínio dos procedimentos armazenados. O DBA pode ver o BL como algo externo ao banco de dados. No entanto, quando o SQL solicita os dados necessários para o BL, o SQL precisa ser enxuto e mesquinho.

Agora, para o encontro das mentes !!!

O desenvolvedor codifica o SP e usa métodos iterativos. O DBA analisa o SP. O DBA determina que uma única instrução SQL pode substituir os métodos iterativos escritos pelo desenvolvedor. O desenvolvedor vê que a instrução SQL sugerida pelo DBA requer a chamada de outro código ou SQL relacionado ao BL que não segue os planos de execução normais da instrução SQL.

À luz disso, a configuração, o ajuste de desempenho e a codificação SP tornam-se uma função da profundidade e intensidade de dados do BL para recuperação de dados. Quanto mais profundidade e intensidade de dados o BL, mais Desenvolvedores e DBA devem estar na mesma página para a quantidade de dados e poder de processamento fornecidos ao Banco de Dados.

CONCLUSÃO

A maneira de recuperação de dados deve sempre envolver os campos Developer e DBA. As concessões sempre devem ser feitas sobre quais métodos de codificação e paradigmas de recuperação de dados podem funcionar juntos, para velocidade e eficiência. Se a preparação dos dados para o código-fonte manipular for feita apenas uma vez antes que o código obtenha os dados, o DBA deverá ditar o uso do SQL lean e médio. Se o BL é algo que o DBA não está em sintonia, as rédeas estão nas mãos do desenvolvedor. É por isso que o DBA deve se ver e fazer parte da equipe do projeto e não uma ilha para si mesmo, enquanto o Desenvolvedor deve permitir que o DBA faça o ajuste fino do SQL, se assim for necessário.

RolandoMySQLDBA
fonte
4

É uma boa pergunta para fazer em um site cheio de DBAs. Esperamos que a maioria das respostas seja "profissional" para manter o banco de dados em um estado ACID e, assim, manter a lógica comercial no banco de dados. :-)

Quanto à minha opinião, acho que você deve implementar a lógica de negócios em seus aplicativos e bancos de dados. Essa abordagem custará mais tempo e dinheiro, mas acho que ela terá uma solução comercial qualitativa melhor.

Ruud van de Beeten
fonte
1
A mesma lógica em duas camadas?
Dez17
Se você deseja criar um novo cliente e precisar armazenar o nome e o número do cliente (que sempre contém 4 números), eu gostaria que o aplicativo verifique se o número do cliente é válido antes de enviar uma instrução SQL para o meu banco de dados (saber que a instrução não passará minha lógica de negócios no banco de dados).
Ruud van de Beeten 17/10/12
2
Toda a lógica de negócios deve ser implementada no banco de dados (portanto, não divida a 'lógica'). Tudo o que você pode verificar facilmente nos aplicativos (por exemplo, com expressões regulares em Javascript) é menos trabalhoso para o banco de dados (em caso de entrada inválida).
Ruud van de Beeten 17/10/12
2
+1 é isso que eu faço, eu só chamá-lo de "colocar o login de negócios no banco de dados e colocar cheques de conveniência no app"
Jack Douglas
1
Você precisa ter uma abordagem sistemática para fazer isso funcionar. A lógica de integridade principal, que faz com que os dados sempre correspondam às expectativas, precisa ser feita primeiro no banco de dados. A seguir, é mantida uma boa comunicação de volta ao aplicativo a partir do banco de dados das condições excepcionais e o cliente pode comunicá-las adequadamente ao usuário. Portanto, antecipar aqueles antes de fazer uma viagem ao banco de dados será a parte mais duplicada e necessariamente terá que ser mantido em sincronia - se você puder minimizar a necessidade de mantê-los sincronizados, será melhor.
Cade Roux
2

Como Adam Musch disse acima, há mais a considerar aqui para desempenho. Utilização do CPU. Uso de memória.

Bloqueie coisas obviamente erradas de acessar o banco de dados.

  • Eliminar endereços de e-mail que não estejam em conformidade de alguma maneira básica.
  • Verificar comprimentos

Quando você se aprofunda, é quando as decisões precisam ser tomadas. O servidor de banco de dados é um local muito caro para fazer coisas que o cliente poderia fazer facilmente. exemplo: formatação de dados, formatar datas, montar strings, etc. do lado do cliente.

Você faz as contas / processamento no cliente ou no servidor de banco de dados? Para mim, isso depende da complexidade e do número de registros envolvidos. A lógica de negócios deve realmente ser feita no próprio banco de dados para que tudo seja tratado da mesma maneira.
Você realmente deve criar uma API de visualizações para ler e procs armazenados para gravar os dados no banco de dados e evitar dores de cabeça no futuro.

Use os pontos fortes de cada extremidade em seu benefício.

Matt M
fonte