Quando devo usar procedimentos armazenados?

15

Se eu tiver toda a minha lógica de negócios em código e fizer uso do Entity Framework, em quais situações (se houver alguma) seria melhor mover alguma lógica de negócios para um procedimento armazenado, em vez de mantê-la tudo em código?

Para ser claro, quero dizer em conjunto com a configuração atual (lógica de negócios no código), não em vez de. Já vi várias perguntas semelhantes que estão pedindo os prós e contras de ter toda a lógica de negócios em procedimentos armazenados, mas não encontrei muito sobre o uso moderado de procedimentos armazenados para a lógica de caso de borda, mantendo o restante da lógica de negócios no código.

Se isso faz diferença, estou usando o MSSQL e o Entity Framework.

Estas são as situações em que usei procedimentos armazenados antes:

  • Um relatório complicado que levava minutos para ser executado (essa era uma página em um aplicativo da web). Eu descobri que eu poderia escrever SQL que era muito mais eficiente (levando apenas alguns segundos para rodar) do que o que o LINQ estava fornecendo.
  • Um aplicativo da Web precisava ler e gravar em algumas tabelas em um banco de dados separado que continha muitas outras informações sensíveis que eram irrelevantes para o aplicativo. Em vez de dar acesso a tudo, usei um procedimento armazenado que apenas faz o que é necessário e só retorna informações limitadas. O aplicativo da Web pode receber acesso apenas a este procedimento armazenado, sem acesso a tabelas, etc.

Outras postagens que eu já vi antes de fazer essa pergunta:

por Amy Barrett 17.08.2016 / 12:57
fonte

6 respostas

8

Você já tem alguns cenários perfeitamente bons.

Existem muitas outras razões também. A EF é muito boa em CRUD e em relatórios bastante diretos. Às vezes, porém, a EF não é a ferramenta perfeita. Algumas outras razões (cenários) para considerar o uso de procedimentos armazenados em combinação com o Entity Framework incluem:

  • Você tem unidades de trabalho complexas, talvez envolvendo muitas tabelas, que não podem ser agrupadas facilmente em uma transação usando os recursos da EF.
  • Seu banco de dados não funciona bem com o EF porque não aproveita a integridade referencial declarativa (restrições de chave estrangeira). Geralmente, esse é um cenário ruim para se encontrar, mas às vezes há cenários apropriados, como bancos de dados usados para processos ETL.
  • Você precisa trabalhar com dados que ultrapassem os limites do servidor com servidores vinculados.
  • Você tem cenários de recuperação de dados muito complexos em que o SQL "bare-metal" é necessário para garantir um desempenho adequado. Por exemplo, você tem associações complexas que precisam de dicas de consulta para funcionar bem em sua situação específica.
  • Seu aplicativo não tem permissões CRUD completas em uma tabela, mas seu aplicativo pode ser executado em um contexto de segurança no qual o servidor confie (identidade do aplicativo, em vez de identidade do usuário, por exemplo). Isso pode surgir em situações em que os DBAs restringem o acesso à tabela apenas aos processos armazenados, pois isso lhes dá um controle mais granular sobre quem pode fazer o quê.

Tenho certeza de que há muitos outros além deles. A maneira de determinar o melhor caminho a seguir em qualquer circunstância particular é usar algum bom senso e focar no objetivo principal, que deve ser escrever código de alta qualidade e fácil manutenção. Escolha a (s) ferramenta (s) que lhe dão esse resultado em cada caso.

    
por 17.08.2016 / 19:00
fonte
2

Talvez faça sentido mudar a questão e encontrar casos em que apenas procedimentos armazenados possam fazer o que você deseja alcançar. Talvez existam casos de uso, onde os procedimentos armazenados se destacam.

If it makes a difference, I am using MSSQL and Entity Framework.

Meu conhecimento sobre EF é limitado, mas, até onde eu posso ver, EF é ( apenas ) um ORM como qualquer outro; e felizmente é capaz de usar SQL bruto .

Se eu considerar seus dois principais pontos:

A complicated report that was taking minutes to run (this was a page in a web app). I found I could write SQL that was much more efficient (only taking seconds to run) than what LINQ was providing.

LINQ / EF estava aquém, ao fazer um relatório. E, como você percebeu, era SQL muito mais rápido do que usar um ORM. Mas fala isso em favor de procedimentos armazenados ou apenas contra o uso do ORM para tudo?

Seu problema pode obviamente ser resolvido com SQL . Se essa consulta foi armazenada e a versão controlada em sua base de código faz - de acordo com o seu exemplo - pelo menos nenhuma diferença .

A web application needed to read and write to a few tables on a separate database which contained a lot of other, sensitive information that was irrelevant to the application. Rather than giving it access to everything, I used a stored procedure that only does what is needed, and only returns limited information. The web application could then be given access to this stored procedure only, without access to any tables etc.

A mesma coisa aqui: uma simples seqüência de conexão e UPDATE e seu problema está resolvido. Este problema pode ser resolvido mesmo com um ORM : simplesmente usa um serviço web na frente do outro DB e o mesmo compartementalization / isolamento é alcançado.

Então, nada para ver aqui.

Olhando para alguns pontos que outros fizeram:

You have complex units of work, perhaps involving many tables, that cannot be wrapped in a transaction easily using the features of EF.

Mas SQL pode fazer isso. Nenhuma mágica envolvida aqui.

Your database does not play well with EF

Novamente: use EF quando apropriado.

You need to work with data that crosses server boundaries with linked servers

Eu não vejo como os procedimentos armazenados ajudam. Então eu não posso ver uma vantagem de procedimentos armazenados; mas talvez alguém lance alguma luz sobre isso.

You have very complex data retrieval scenarios where "bare metal" SQL is needed in order to ensure adequate performance

Novamente: "Limites de EF ".

Your application does not have full CRUD permissions on a table but your application can be allowed to run under a security context that your server trusts

Ok. Eu vou com um talvez .

Até agora apenas um meio ponto foi feito em favor de procedimentos armazenados.

Talvez existam considerações de desempenho que falem em favor de procedimentos armazenados.

1) Armazenar consultas tem o benefício de uma chamada simples para o procedimento armazenado que encapsula a complexidade. Como o planificador de consulta conhece a consulta, é "mais fácil" otimizar. Mas os salvamentos estão com o planejador de consultas sofisticado atual _minimal.

Além disso, mesmo que haja um pequeno custo usando consultas ad hoc , se seus dados estiverem bem estruturados e cuidadosamente indexados, o banco de dados será apenas o < em> gargalo da sua aplicação. Portanto, mesmo que haja um pequeno delta, é negligenciável considerando outros fatores.

2) No entanto, foi argumentado para armazenar complex consultas em um banco de dados. Há duas coisas a considerar:

a) consultas complexas fazem uso maciço da infra-estrutura do banco de dados, o que aumenta à medida que o tempo é gasto para todas as outras consultas. Você não pode executar muitas consultas dispendiosas em paralelo . Isso não fala nem em pro nem em contra procedimentos armazenados, mas em consultas complexas .

b) Se a consulta levar tempo de qualquer maneira, por que se preocupar com ganhos de velocidade pequenos de um procedimento armazenado.

tl; dr

Nada fala diretamente contra procedimentos armazenados. Então, usar procedimentos armazenados é bom - se isso te faz feliz.

Mas, por outro lado: não consigo imaginar um caso de uso > que fale inequivocamente pro.

When should I use stored procedures?

A resposta correta é: Sempre que você gostar . Mas existem outras opções.

    
por 17.08.2016 / 22:24
fonte
0

Para o seu caso específico, uma vez que você está usando a estrutura da entidade, deve-se considerar o uso de procedimentos armazenados quando a estrutura da entidade não atende a um requisito ou preocupação.

A estrutura da entidade faz um trabalho decente e o desempenho será próximo ou igual ao uso de procedimentos armazenados. Você escolheu a estrutura da entidade porque não queria se preocupar com SQL e permitiria que a estrutura gerasse o SQL para você.

Mas pode haver um caso extremo em que a estrutura da entidade fica aquém e não pode atender às suas necessidades. Nesse caso, é possível escrever o SQL manualmente usando um procedimento armazenado ou consulta parametrizada e, em seguida, usar a estrutura de entidade para chamar diretamente essa instrução / instrução SQL armazenada.

Portanto, eu não moveria nada para um procedimento armazenado, a menos que a estrutura que está sendo empregada não atenda ao requisito.

Acho que a pior coisa que pode acontecer é escolher o framework da entidade e, em seguida, gravar todos os procedimentos armazenados. Agora temos uma camada extra que não agrega valor.

    
por 17.08.2016 / 18:07
fonte
0

Ter uma necessidade técnica não é a escolha mais provável. Os programadores preferem suas ferramentas e geralmente são mais adaptados para resolver seus problemas com eles. Colocar lógica em um sproc será a exceção. Dívida técnica e devs futuros tendo que levar tempo para trabalhar com uma exceção devem ser considerados. Pode haver um aumento de desempenho em seu RDBMS específico, que é mais fácil de implementar em um sproc ou talvez até mesmo outro objeto db, como uma exibição indexada.

Haverá momentos em que você precisará de dados de um banco de dados e não poderá obtê-los do código do aplicativo. Em muitas situações de grandes empresas / empresas, as necessidades de negócios podem exceder o alcance do departamento de TI. As empresas são compradas e vendidas e seus aplicativos vêm e vão com eles. As agências reguladoras e os bancos não se importam se você não pode criar seu aplicativo altamente escalável e com códigos belos. Eles podem dificultar a vida do negócio, então você tem que fazê-lo.

Encontrei situações em que aplicativos de terceiros ou ferramentas de geração de relatórios não permitem que você obtenha seu código. Sem código aberto, sem API, sem interface web e sem serviços. A única coisa que eles têm é a sua própria ferramenta de escrita de relatórios especiais que só funciona com objetos de banco de dados: tabelas, visualizações, sprocs, funções definidas pelo usuário, etc. Você coloca a lógica onde quer que você possa chegar nela.

Se você tem um DBA que é muito bom em escrever procedimentos armazenados, pode aproveitar esse talento em algumas situações. Você pode querer acionar um backup do seu aplicativo, porque você vai fazer uma grande mudança de dados, então por que não usar o que seu dba usa?

Algumas solicitações ad hoc são mais fáceis de escrever um procedimento até que você possa obter todas as funcionalidades do seu aplicativo. Nós odiamos isso. Nós empurramos de volta, mas o show deve continuar.

    
por 17.08.2016 / 18:48
fonte
0

Aconselho vivamente contra a colocação de qualquer lógica de negócio em um procedimento armazenado. No entanto, pode haver um caso (você listou dois bons exemplos) onde é preferível colocar a lógica de acesso a dados .

De modo geral, se você se sentir tentado a usar o SP, é um sinal (um cheiro de código) sugerindo que seu modelo de dados não está adequado às suas necessidades.

Editar: Quando os desenvolvedores me perguntam sobre lógica de acesso de dados / negócios, eu digo que a lógica de negócios é sobre como os dados se comportam e interagem, enquanto a lógica de acesso a dados é sobre como os dados são armazenados e recuperados.

Por exemplo: em seu modelo de domínio, você pode ter as entidades "Student" e "Teacher", ambas derivadas de "Person". (Não estou dizendo que isso é o preferido, apenas um exemplo). Isso pode ser armazenado em um banco de dados relacional como uma, duas ou três tabelas. A escolha depende de quantas propriedades eles compartilham e dos requisitos de desempenho de leitura / gravação.

Na lógica de negócios, não importa como essas entidades são armazenadas. (ou se eles residem em um RDB). A lógica de acesso a dados é toda sobre como eles são fisicamente armazenados.

Portanto, em relação à pergunta original: Se um procedimento armazenado tornar o armazenamento e a recuperação de dados mais eficientes (ou mais robustos), você terá um caso. Se o procedimento armazenado for apenas para impor uma regra que seja válida independentemente de como os dados são armazenados, evite-os. Isso torna seu código mais strongmente acoplado ao banco de dados.

    
por 17.08.2016 / 13:29
fonte
-4

Acho que há três questões aqui.

  1. A lógica de negócios no SQL é ruim. Mesmo que seja executado mais rapidamente individualmente, não é escalável.

  2. Tradionalmente, os SPROCs devem sempre ser usados para todos os dados de acesso como uma camada de abstração. Permitir que um DBA introduza alterações no desempenho ou em outras datalayer sem afetar os aplicativos consumidores.

  3. O EF não funciona bem com sprocs. Você perderá muitos recursos "bons" e ganhos de produtividade, deixando de lado a geração de consultas dinâmicas do Linq.

Então, meu conselho geral seria

  • Use SPROCs para todas as consultas SQL,

  • Não coloque lógica de negócios ou qualquer tipo de loop neles,

  • Não use EF.

por 17.08.2016 / 14:23
fonte