Pergunta

Quais são os argumentos a favor e contra a lógica de negócios em procedimentos armazenados?

Foi útil?

Solução

Contra procedimentos armazenados: lógica de negócios no espaço de programação

eu colocar um valor alto no poder de expressão, e eu não encontrar o espaço SQL para ser tudo o que expressivo. Use as melhores ferramentas que você tem na mão para as tarefas mais apropriadas. Brincando com a lógica e os conceitos de ordem superior é o melhor feito ao mais alto nível. Consequentemente, o armazenamento e manipulação de dados em massa é o melhor feito no nível do servidor, provavelmente em procedimentos armazenados.

Mas isso depende. Se você tiver vários aplicativos que interagem com o mecanismo de um armazenamento e você quer se certificar de que mantém a sua integridade e fluxo de trabalho, então você deve descarregar toda a lógica no servidor de banco de dados. Ou, estar preparado para gerenciar o desenvolvimento simultâneo em várias aplicações.

Outras dicas

Eu sou completamente contra ela. Um dos maiores motivos é a primeira razão Earino afirmou - que vive em um só lugar. Você não pode integrá-lo no controle de origem muito facilmente. É quase impossível ter dois devs trabalhando em um proc armazenados ao mesmo tempo.

A minha outra queixa principal é que o SQL não é apenas muito bom em representação lógica complexa. Você não tem o conceito de escopo, o código tende a ser copy-colado porque há uma menor capacidade de reutilização de código (em oposição a uma linguagem OO).

Você tem que dar aos desenvolvedores acesso ao banco de dados para desenvolver lá. Em muitas organizações Tenho trabalhado para as pessoas de dados estão em um mundo diferente do que os devs, com diferentes permissões, etc. Manter os devs fora do banco de dados, nestes casos, seria mais difícil.

Eu sou da escola de pensamento que diz que, enquanto a lógica de negócios:

  • vive em um local
  • onde é devidamente documentado
  • acesso adequado é fornecido através de serviços que podem ser de baixo acoplamento
  • através de uma interface de abstraída
  • publicada

Eu não me importo se a lógica vive em um procedimento armazenado, em uma camada intermediária J2EE, em um sistema especialista, ou onde quer clips. Não importa onde você armazenar a nossa lógica de negócios da "lei da conservação da miséria" vai garantir que alguém vai dizer que foi a ideia errada, porque as necessidades componente / repositório X para ser trocado por tecnologia / método Y.

Alguns pensamentos: Por favor note que este é uma resposta centrada Java, mas sua a maior parte dos meus recentes (últimos 10 anos) experiência

(1) desenvolvimento simultâneo por um (a grande) equipe de desenvolvedores. Se você é aplicação é suficientemente complexo que cada desenvolvedor não pode criar a sua própria versão privada do DB (com ligações atendidas / dados REF / etc ...), é muito difícil ter toda uma equipe de desenvolvedores de todos os que trabalham em o mesmo conjunto de PL-SQL (por exemplo) pacotes ao mesmo tempo armazenados em um DEVL DB compartilhado? Em seguida, seu preso (a minha experiência) com o trabalho em um banco de dados com procedimentos / incompatibilidade de código para tabelas inválidos como as pessoas fazem mudanças ...

Como um arquiteto Java, eu acho que é muito mais fácil fazer com que cada colaborador tem uma instância JBoss privado em seu desktop e trabalhar facilmente em seu próprio conjunto de funcionalidades, e integrando em seu próprio ritmo, sem afetar todos os outros ... que traz eu ...

(2) conjuntos de ferramentas de integração contínua Enquanto existem alguns 'conceitos' semelhantes em todo o mundo DB, a minha experiência tem me mostrado que a combinação de (i estou meus atuais favs best-of-breed pegar aqui):

  • mvn - sistema de compilação
  • JUnit - automatizado de teste de unidade
  • nexo - gerente repo (gerencia versão ciclos de vida, instantâneos e lançamentos do artefato)
  • hudson - servidor de construção ci
  • sonar - análise estática relatórios de cobertura de ferramenta / code / MUITO mais

A execução de um projeto de grande usando todas as ferramentas gratuitas () acima permite uma forma consistente / fácil de entregar XP para as massas e aplicar controles de qualidade ao longo de toda a equipe de TI. A Oracle / PL-SQL não tem os conjuntos de ferramentas para combinar

(3) ferramentas / bibliotecas / etc ... Java tem acesso a um conjunto incrível de serviços que outras plataformas não podem tocar - alguns gratuitos, outros não. mesmo os mais básicos, como log4j (sim, eles têm-lo para PL / SQL, mas pulease ... não é quase o mesmo) permite coisas como permitir que os desenvolvedores criem logging com flexibilidade ajustável que pode ser alterado na mosca (perfeito para dubugging) . documentação da API automatizado (via javadoc). Automatizados relatórios de cobertura de teste de unidade. IDEs incríveis (Eclipse) com depuradores integrados / autodeploy para servidores de aplicação. Uma API para a interface com cada tipo de serviço sob o sol, bibliotecas de código aberto para fazer qualquer coisa, e 100% de apoio por cada fornecedor

(4) reutilização de serviços. o que alguém comentou sobre é verdade. Se você tiver pesados ?? dados orientado regras de negócio , em seguida, você pode argumentar que estes devem viver na camada DB. Por quê? para evitar ter a camada intermediária (s) todos ter que duplicar essa lógica.

Mas o mesmo pode ser dito para as regras de negócios que são não dados orientado ou suficientemente complexo que OO é uma escolha mais natural . Se você ficar toda a lógica de negócios no DB, então eles estão disponíveis apenas através do DB.

  • E se você quer ter validação feita no cliente ou aplicativo Camada Intermediária e salvar um de ida e volta para o DB?
  • E se você quiser cache de leitura apenas dados na camada intermediária (para desempenho) e têm regras de negócio executar contra os dados armazenados em cache?
  • E se você tem um serviço de camada intermediária que não requer acesso DB, ou você tem um cliente que pode fornecer seus próprios dados?
  • E se os dados porção dependente das regras de negócio, então, precisa serviços externos de acesso? Então você acaba com uma lógica empresarial fragmentada que se parece com isso:

i

retCode = validateSomeDate(date);
if (retCode == 1) then
   evaluateIfCustomerGetsEmail(...)//probably more stored proc invocations here...
   sendEmailMsg(....)
else if (retCode == 2) then
   performOtherBizLogicStuf(...) //again, may need data, may not need data
   triggerExternalsystemToDoSomething(...) //may not be accessible via PL/SQL 
fi

Estou certo de que temos todos os sistemas visto escrito como o descrito acima e teve de depurá-los em 2AM. É extremamente difícil ter uma noção coerente de um processo complexo, quando a lógica de negócios está fragmentado entre os níveis e, em alguns casos, chega a ser impossível de manter.

"Você não pode integrá-lo no controle de origem muito facilmente." - se você colocar o código que cria o proc armazenado em um script que é a versão controlada, essa objeção vai embora. Se você seguir as idéias de banco de dados ágeis de Scott Ambler, que é exatamente o que você deve fazer.

Nem todos os desenvolvedores são bons modeladores de dados. Não consigo pensar em esquemas horríveis criados por desenvolvedores que achavam que um conhecimento brincar de SQL fez deles especialistas em banco de dados. Eu acho que há um monte de valor para ter desenvolvedores que trabalham com DBAs e dados modeladores.

Se apenas um aplicativo usa o banco de dados, eu diria que a lógica de negócio podem aparecer na camada intermediária. Se muitos aplicativos compartilhar o banco de dados, talvez seja melhor para colocá-lo no banco de dados.

SOA oferece um meio termo: Serviços de possuir seus dados. Apenas o serviço tem acesso aos dados; ficando a meios de dados passando pelo serviço. Nesse caso, é possível colocar as regras em qualquer lugar.

Os pedidos vêm e vão, mas restos de dados.

Mais uma razão para não armazenar lógica de negócios em sprocs - habilidades de escala limitada da DB. Ele é uma situação muito comum, onde seu banco de dados é o seu gargalo, é por isso que é uma boa idéia para tirar o máximo de carga do DB possível.

As minhas poucas observações:

Em favor de procedimentos armazenados:

  • depois de algum tempo de vida do projeto, na maioria dos casos, o gargalo é o banco de dados não o servidor web - e procedimentos armazenados são muito, muito mais rápido

  • usando SQL Profiler com ORM gerado consultas SQL é muito difícil; isso é fácil com procedimentos armazenados

  • Você pode implantar uma correção para procedimento armazenado instantaneamente, sem uma janela de serviço

  • para o desempenho, é mais fácil para otimizar um procedimento armazenado que ORM-code

  • Você pode ter muitas aplicações usando o mesmo db / procs armazenados

  • qualquer cenário de dados complexos é um voto para procedimentos armazenados

Em favor de application / ORM:

  • Você pode usar repositório de código (com procedimentos armazenados ainda é possível, mas caro)

  • java / c # linguagem é uma ferramenta melhor para expressar a lógica de negócios

  • java / c # é mais fácil de depurar (exceto para o SQL ORM gerado dinamicamente)

  • independência do motor de banco de dados (no entanto, isso não é muito provável que um projeto vai banco de dados de mudança para outro)

  • ORM fornece modelo de dados que é fácil de usar

Na minha opinião: para grandes projectos - ir para procedimentos armazenados, para os outros - Aplicação / ORM vai funcionar bem.

No final de um dia, a única coisa que importa é o banco de dados.

A lógica de negócios deve ser encapsulado em um só lugar. Nós podemos garantir que a lógica é sempre correr e correr de forma consistente. Usando classes que toda atividade envolvendo uma entidade no banco de dados deve ser executado através podemos garantir que todas as validação é executado corretamente. Há um lugar para este código e qualquer desenvolvedor do projeto pode facilmente abrir esta classe e ver a lógica (porque a documentação pode e não ficar fora da data, o código é a única forma confiável de documentação).

Isto é difícil de fazer com procedimentos armazenados. Você pode ter mais de um sproc lidar com a mesma tabela (s). Encadeamento de vários sprocs em conjunto para que reside a lógica em um só leva pesado. Essa é uma greve. Como você determina "Quais são todas as regras de negócio em torno entidade X" no banco de dados? Divirta-se procurando milhares de sprocs tentando rastrear isso para baixo.

O número dois é que você está amarrando a sua lógica de negócios para o seu mecanismo de persistência. Você não pode armazenar todos os seus dados no mesmo banco de dados, ou alguns podem residir em XML etc. Este tipo de inconsistência é difícil sobre o desenvolvedor.

A validação é difícil de executar se a lógica reside apenas no banco de dados. Você realmente chamar um sproc para validar todos os campos no formulário de entrada de dados? As regras de validação e lógica de negócios são primos próximos. Esta lógica devem ser todos realizados no mesmo lugar!

+: servidor SQL, por vezes, otimiza o código

+: Você é forçado a passar parâmetros, o que limita a questões de injeção de SQL

-: O seu código depende de uma única base de dados (alguns dbs não tem sequer SP)

-: Para alterar o código que você precisa para se conectar ao banco de dados

-: Lógica não é bem organizado

Pessoalmente sou contra, mas eu tinha que usá-lo uma vez em um site muito ocupado. Usando SP em MS SQL trouxe enormes benefícios, mas uma vez eu implementado cache esses benefícios não eram tão grande anymore.

Há um ditado ...

Quando tudo que você tem é um martelo, tudo parece um prego.

Na minha humilde opinião, não existe uma resposta que vai caber todas as circunstâncias. Parece-me que muitas pessoas simplesmente assumir que a colocação de lógica de negócios no banco de dados é sempre errado.

Um monte de trabalho tem sido feito para tornar o processamento de transações, especialmente operações em massa, muito eficiente quando feito no lado do banco de dados. Além disso, o gerenciamento de código em bancos de dados melhorou muito desde que a maioria das opiniões contra bancos de dados foram formados.

Eu acho que é errado considerar o servidor de banco de dados como apenas uma camada de persistência. Se suas atividades de processamento são mais eficientes quando feito no DB servidor, em seguida, fazê-las lá.

Se não, então fazê-las em outro lugar.

Tudo se resume ao que melhor se adapta a aplicação que você está trabalhando no momento, a equipe com quem você está trabalhando e o cliente que você contratou.

Isso apenas meus 2 centavos.

Você pode lógica de negócios de teste da unidade quando o seu em uma camada lógica de negócios. Se ele é separar completamente as operações Persistência pode ser ridicularizado por isso que você está testando somente a BL. Um procedimento armazenado é muito mais difícil de manter / depuração teste / unidade do que, por exemplo, LINQ e C #.

DBMS! = Servidor de aplicativos

  • A programação funcional (Procedimento armazenado DB) vs OOP. Para grandes programas é OOP apenas padrão.
  • IDE - eclipse, IntelliJ, netbeans com todos os plugins para depuração, testes e análise funciona apenas com linguagens de programação real. ferramentas de código estático .
  • O controle de versão, se você obter um para PLSQL & co. é ótimo. Se você receber "vista Sincronizar" dirigir de você ide -. Você é real o sortudo
  • Escala seu sistema. Para o sistema DB é o inferno. Você precisa de hardware caro para outros "nós". Replicação. E, provavelmente, licença para cada nó. Não esqueça que você ainda estão em "programação funcional" e esforço para entender e manter tais sistemas é muito maior.
  • Você está preso com o seu DB, tente mudar ou adicionar um novo nome de outra empresa
  • E assim por diante ...

procedimento armazenado por lógica de negócios é uma prática ruim hoje. Use arquitetura 3-Tier vez.

O desempenho será massivamente melhorado movendo a lógica para os procedimentos armazenados, especialmente se as transações explícitas estão envolvidos.

Na minha experiência, os desenvolvedores de aplicativos não são muito bons em escrever código de banco de dados otimizado, e não tendem a pensar sobre problemas de concorrência ou de desempenho.
Se a lógica do negócio é mantido na camada de aplicação, você tende a ter a deslocar grandes quantidades de dados (muitas vezes em muitos round-trips) em toda a rede, duplicá-lo na memória no servidor de DB, e pelo menos uma vez no servidor de aplicações, e fazer uma carga de processamento de linha por linha no aplicativo enquanto você está segurando aberta uma transação. Em seguida, os desenvolvedores de aplicativos se queixam de que o banco de dados é lenta e mantém travado.

Se você colocar a lógica no DB onde quer que seja possível, você só tendem a passar alguns parâmetros em toda a rede, as transações não são realizadas enquanto você espera para recursos de rede, e toda a coisa vai como um relâmpago untada. Bases de dados deve, naturalmente, ir no controle de origem como qualquer outro código fonte .. há uma abundância de ferramentas para isso.

@ Nick "Eu sou completamente contra ela Um dos maiores motivos é a Earino primeira razão afirmou -... Que vive em um lugar que você não pode integrá-lo no controle de origem muito facilmente É quase impossível ter dois devs trabalhando em um procedimento armazenado ao mesmo tempo ".

Não que eu estou discutindo para colocar a lógica de negócios em procedimentos armazenados (todo o contrário). Mas essas razões que você apresentadas não fazem sentido. Um procedimento armazenado é simplesmente um sql / DDL artefato que podem ser armazenados no controle de origem, e que também é um artefato de implementação (isto é, algo entregue ao dba para implantação, da mesma maneira que você iria entregar sua guerra / orelha artefatos para as TI / liasons de implantação) um ou mais desenvolvedores podem trabalhar no mesmo procedimento armazenado fora de controle de origem apenas da mesma forma que você vai fazer com o código fonte velho liso -. ramificando, versionamento e fundindo

Agora, se a única cópia do procedimento armazenado (e os pacotes que os contenham) só existem no banco de dados, então, obviamente, você não pode controlar isso com controle de origem (e todos os problemas associados a isso). No entanto, isso não é um problema de procedimento armazenado, mas um problema de inépcia no que diz respeito de como usar esse código. É como igualmente uma exposição de inépcia como tendo apenas uma cópia de seu código fonte viva na produção.

Eu trabalhei em sistemas com grandes quantidades de código, Java e PLSQL / DDLs e todos foram versionadas em clearcase. Eles foram todos tratados como código-fonte que seria compilado e implantado com um processo rigoroso, com equipes diferentes trabalhando neles. Nunca tive qualquer problema como o que você está descrevendo.

Não são específicos do contexto razões para não colocar lógica de negócios em procedimentos armazenados, mas estes não são os válidos.

projetos de orçamento alto: Se você está mantendo seu dados atualizados na memória e salvar as alterações no disco periodicamente, você gostaria de lógica de negócios alça para além do servidor db. caso de uso: servir dados de carneiro, mecanismos de cache complexas

.

projetos de baixo orçamento: Se você está mantendo a dados actualizados no disco e sua apresentação é dependente de leituras de disco, manipulação lógica de negócios em procedimentos armazenados pode poupar tempo de desenvolvimento. caso de uso: servir dados do disco

Existem diferentes tipos de "lógica de negócios". Considere particionamento-lo com base em como ele está relacionado a outras camadas ou serviços. Aqui estão algumas regras de ouro de uma perspectiva MVC:

a) No banco de dados (procedimento armazenado) se é na sua maioria relacionados com dados, e pode ser feito com junta e relativamente simples, onde e SELECT cláusulas.

b) No controlador se é principalmente roteamento ou despachar relacionados; isto é, o controle de fluxo UI maior escala em termos de seleção de tela ou recurso.

c) No modelo ou view-modelo se envolve cálculos e / ou condicionais complexos ou intrincados.

d) Na visão (como Navalha) se é principalmente um problema de exibição, como "amigável" re-formatação e relativamente simples de implementar. (Se é complexo, considere colocá-lo em um modelo de exibição.)

A minha regra de ouro (uma vez eu reconheci o que era pelo pensamento sobre a questão) é que os procedimentos armazenados deve conter código que a integridade de dados assegura dentro do banco de dados, se o procedimento armazenado proíbe certa inserção de dados, exclusão ou modificação, ou marcas outras mudanças necessárias para a consistência dos dados. A lógica de negócios, especialmente lógica que não pode ser implementado em um punhado de operações baseadas em conjunto, devem ser implementadas em outros lugares. Bancos de dados não são aplicações. Bancos de dados deve ser a autoridade final para relacionamentos e restrições, mesmo que as regras de negócio também são implementadas em outros lugares para, digamos, o fornecimento de feedback no código de interface de usuário que reduz postbacks de um servidor web ou elimina caso contrário acessos desnecessários em um servidor ocupado. Pode-se discutir se "a consistência dos dados" inclui o resultado do processamento complexo de regras de negócios complexos, mas eu acho que é geralmente clara uma vez que o contexto é entendido. Nem todas as regras de negócio são implementadas como relações de dados ou restrições. Nem todas as operações em um procedimento armazenado são mais rápidos do que o código executado em um processo separado, mesmo em um processo em execução em uma máquina separada através de uma rede. Eu fiz recentemente uma demonstração mostrando que muitas operações no SSIS, por exemplo, (INSERT INTO () SELECT FROM) executar mais rápido no SSIS que funciona através de uma rede em uma máquina separada do que correr em um procedimento armazenado (que também insere os resultados para um banco de dados em toda a rede). Este é um resultado quase inacreditável (onde SSIS é mais rápido do que instruções SQL matérias), e demonstra que a descoberta do melhor otimização de quaisquer problemas de desempenho vem da realidade (testes) e não de lógica baseado em apenas alguns conceitos. (Nós ainda temos de tomar decisões sobre o que prova por regras de ouro aprendido pela experiência.) (SSIS executada mais rapidamente através da implementação automaticamente multithreading e oleodutos, usando BULK INSERT, mesmo onde não foi especificado na instrução SQL cru, e enviar lotes de inserções em um segmento enquanto criando inserções em massa adicionais sobre outros tópicos. neste caso, é realizada cerca de duas vezes mais rápido que instruções SQL crus.) Quando eu usei a programação teach e cursos de SQL Server, os usuários PowerBuilder parecia ter a declaração "Native drivers fornecem o acesso a dados mais rápido" queimado para a sua língua, e embora possa ser justificada por meio adicional (não reconhecido por eles) explicação, o pensamento por trás disso é enganosa.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top