Quand dois-je utiliser des procédures stockées?

19

Si j'ai toute ma logique métier dans le code et que j'utilise Entity Framework, dans quelles situations (le cas échéant) serais-je mieux de déplacer une logique métier vers une procédure stockée, au lieu de tout garder dans le code?

Pour être clair, je veux dire en conjonction avec la configuration actuelle (logique métier dans le code), pas à la place de. J'ai vu un certain nombre de questions similaires qui demandent les avantages et les inconvénients d'avoir toute la logique métier dans les procédures stockées, mais je n'ai pas trouvé grand-chose concernant l'utilisation parcimonieuse des procédures stockées pour la logique de cas de bord, tout en conservant le reste de la logique métier dans du code.

Si cela fait une différence, j'utilise MSSQL et Entity Framework.


Ce sont les situations où j'ai déjà utilisé des procédures stockées:

  • Un rapport compliqué qui prenait des minutes à exécuter (c'était une page dans une application web). J'ai trouvé que je pouvais écrire du SQL beaucoup plus efficace (ne prenant que quelques secondes à exécuter) que ce que LINQ fournissait.
  • Une application Web devait lire et écrire dans quelques tables d'une base de données distincte qui contenait beaucoup d'autres informations sensibles qui n'étaient pas pertinentes pour l'application. Plutôt que de lui donner accès à tout, j'ai utilisé une procédure stockée qui ne fait que ce qui est nécessaire et ne renvoie que des informations limitées. L'application Web pourrait alors avoir accès uniquement à cette procédure stockée, sans accès à des tables, etc.

Autres articles que j'ai consultés avant de poser cette question:

Amy Barrett
la source
4
Vos deux situations sont des raisons parfaitement légitimes d'écrire des procédures stockées. Demandez-vous pourquoi ils sont légitimes?
Robert Harvey
@RobertHarvey Je m'assurais qu'ils étaient légitimes et recherchais d'autres scénarios ou raisons pour lesquels vous pourriez faire une exception et écrire une procédure stockée plutôt que de la garder dans le code.
Amy Barrett
Vous feriez une exception et écrivez une procédure stockée lorsque vous déterminez qu'elle résout un problème mieux que les autres techniques à votre disposition, ce qui est exactement ce que vous avez fait.
Robert Harvey

Réponses:

10

Vous avez déjà quelques scénarios parfaitement bons.

Il y a aussi beaucoup d'autres raisons. EF est vraiment bon au CRUD et au reporting assez simple. Parfois, cependant, EF n'est pas l'outil parfait. Voici d'autres raisons (scénarios) d'envisager l'utilisation de procédures stockées en combinaison avec Entity Framework:

  • Vous avez des unités de travail complexes, impliquant peut-être de nombreuses tables, qui ne peuvent pas être encapsulées facilement dans une transaction à l'aide des fonctionnalités d'EF.
  • Votre base de données ne fonctionne pas bien avec EF car elle ne tire pas parti de l'intégrité référentielle déclarative (contraintes de clé étrangère). Il s'agit généralement d'un mauvais scénario dans lequel vous vous trouvez, mais il existe parfois des scénarios appropriés, tels que des bases de données utilisées pour les processus ETL.
  • Vous devez travailler avec des données qui traversent les frontières du serveur avec des serveurs liés.
  • Vous disposez de scénarios de récupération de données très complexes où un SQL «nu» est nécessaire pour garantir des performances adéquates. Par exemple, vous avez des jointures complexes qui nécessitent des conseils de requête pour bien fonctionner dans votre situation spécifique.
  • Votre application ne dispose pas des autorisations CRUD complètes sur une table, mais votre application peut être autorisée à s'exécuter dans un contexte de sécurité approuvé par votre serveur (identité de l'application, plutôt que l'identité de l'utilisateur, par exemple). Cela peut se produire dans des situations où les administrateurs de base de données limitent l'accès aux tables aux proc stockés uniquement parce que cela leur donne un contrôle plus granulaire sur qui peut faire quoi.

Je suis sûr qu'il y en a beaucoup plus en plus. La façon de déterminer la meilleure voie à suivre dans toute circonstance particulière consiste à faire preuve de bon sens et à se concentrer sur l'objectif principal, qui devrait être d'écrire du code de haute qualité et facile à maintenir. Choisissez le ou les outils qui vous donnent ce résultat dans chaque cas.

Joel Brown
la source
Merci Joel, vous avez mentionné quelques autres scénarios auxquels je n'avais pas pensé.
Amy Barrett
Bonne réponse. Cependant, je me demande si vous avez de nombreux utilisateurs connectés à la base de données et exécutant des requêtes complexes ou des procédures stockées, ne finirez-vous pas par mettre beaucoup de charge sur le serveur de base de données?
Ripal Barot
1
@RipalBarot Il ne fait aucun doute que plus la charge de travail se déroule (plus d'utilisateurs, de requêtes plus complexes), plus les exigences seront lourdes pour votre serveur de base de données. Une chose à garder à l'esprit, cependant, est que l'utilisation de procédures stockées plutôt que d'ORM comme Entity Framework peut souvent réduire la charge de travail (comparativement) car les procédures stockées peuvent avoir des plans de requête précompilés. Lorsqu'une requête provient d'un ORM, le SGBD doit souvent commencer par trouver comment gérer la requête. Lorsque vous appelez une procédure stockée équivalente, la base de données sait déjà comment l'exécuter efficacement.
Joel Brown
2

Peut-être que cela a du sens, de tourner la question et de trouver des cas où seules les procédures stockées pourraient faire, ce que vous voulez réaliser. Il existe peut-être vraiment des cas d'utilisation, où les procédures stockées se démarquent.

Si cela fait une différence, j'utilise MSSQL et Entity Framework.

Mes connaissances sur EF sont limitées, mais pour autant que je puisse voir, EF est ( juste ) un ORM comme les autres; et est heureusement capable d'utiliser du SQL brut .

Si je prends vos deux points principaux:

Un rapport compliqué qui prenait des minutes à exécuter (c'était une page dans une application web). J'ai trouvé que je pouvais écrire du SQL beaucoup plus efficace (ne prenant que quelques secondes à exécuter) que ce que LINQ fournissait.

LINQ / EF n'était pas à la hauteur lors de la rédaction d'un rapport. Et comme vous l'avez remarqué, c'était SQLbeaucoup plus rapide que d'utiliser un ORM. Mais parle-t-il en faveur des procédures stockées ou seulement contre l'utilisation de l' ORM pour tout?

Votre problème pourrait évidemment être résolu avec SQL . Si cette requête a été stockée et la version contrôlée dans votre base de code ne fait - selon votre exemple - au moins aucune différence .

Une application Web devait lire et écrire dans quelques tables d'une base de données distincte qui contenait beaucoup d'autres informations sensibles qui n'étaient pas pertinentes pour l'application. Plutôt que de lui donner accès à tout, j'ai utilisé une procédure stockée qui ne fait que ce qui est nécessaire et ne renvoie que des informations limitées. L'application Web pourrait alors avoir accès uniquement à cette procédure stockée, sans accès à des tables, etc.

Même chose ici: une simple chaîne de connexion et et UPDATE et votre problème est terminé. Ce problème pourrait être résolu même avec un ORM : il suffit d' utiliser un webservice en face de l'autre DB et la même segmentation / isolation est obtenue.

Donc rien à voir ici.

En examinant certains points que d'autres ont soulevés:

Vous avez des unités de travail complexes, impliquant peut-être de nombreuses tables, qui ne peuvent pas être encapsulées facilement dans une transaction à l'aide des fonctionnalités d'EF.

Mais SQLpeut le faire. Pas de magie impliquée ici.

Votre base de données ne fonctionne pas bien avec EF

Encore une fois: utilisez EF lorsque cela est approprié.

Vous devez travailler avec des données qui traversent les frontières du serveur avec des serveurs liés

Je ne vois pas comment les procédures stockées aident. Je ne peux donc pas voir un avantage des procédures stockées; mais peut-être que quelqu'un fait la lumière là-dessus.

Vous avez des scénarios de récupération de données très complexes où un SQL «nu» est nécessaire afin d'assurer des performances adéquates

Encore une fois: "Limites d' EF ".

Votre application ne dispose pas des autorisations CRUD complètes sur une table, mais votre application peut être autorisée à s'exécuter dans un contexte de sécurité auquel votre serveur fait confiance

D'accord. Je pars avec un peut - être .

Jusqu'à présent, seulement un demi- point a été fait en faveur des procédures stockées.


Il existe peut-être des considérations de performances, qui parlent en faveur des procédures stockées.

1) Le stockage des requêtes présente l'avantage d'un simple appel à la procédure stockée qui résume la complexité. Étant donné que le planificateur de requêtes connaît la requête, son optimisation est "plus facile". Mais les sauvegardes se font avec le planificateur de requêtes sophistiqué actuel _minimal.

En plus de cela, même s'il y a un léger coût en utilisant des requêtes ad hoc , si vos données sont bien structurées et soigneusement indexées, la base de données n'est que le goulot d' étranglement de votre application. Donc, même s'il y a un petit delta, il est négligeable compte tenu d'autres facteurs.

2) Néanmoins, il a été plaidé pour le stockage de requêtes complexes dans une base de données. Il y a deux choses à considérer:

a) les requêtes complexes utilisent massivement l'infrastructure DB, ce qui augmente les temps de réponse pour toutes les autres requêtes. Vous ne pouvez pas exécuter de nombreuses requêtes coûteuses en parallèle . Cela ne parle ni pour ni contre les procédures stockées, mais contre les requêtes complexes .

b) Si la requête prend de toute façon du temps, pourquoi s'embêter avec de petites victoires de vitesse d'une procédure stockée.

tl; dr

Rien ne parle directement contre les procédures stockées. Il est donc acceptable d'utiliser des procédures stockées - si cela vous rend heureux.

Mais d'un autre côté: je ne pouvais pas imaginer un cas d'utilisation approprié qui parle sans équivoque pro.

Quand dois-je utiliser des procédures stockées?

La bonne réponse est: quand vous le souhaitez . Mais il existe d'autres options.

Thomas Junk
la source
0

Dans votre cas spécifique, étant donné que vous utilisez l'infrastructure d'entité, il convient d'envisager d'utiliser des procédures stockées lorsque l'infrastructure d'entité ne répond pas à une exigence ou à une préoccupation.

Le cadre d'entité fait un travail décent et les performances seront proches ou égales à l'utilisation de procédures stockées. Vous avez choisi le framework d'entité parce que vous ne vouliez pas vous préoccuper de SQL et laissez le framework générer le SQL pour vous.

Mais il peut y avoir un cas limite où le cadre d'entité est défaillant et ne peut pas répondre à vos besoins. Dans ce cas, on écrit le SQL à la main à l'aide d'une procédure stockée ou d'une requête paramétrée, puis on utilise le cadre d'entité pour appeler directement cette procédure stockée / instruction SQL.

Donc, je ne déplacerais rien vers une procédure stockée à moins que le cadre utilisé ne puisse pas répondre à l'exigence.

Je pense que la pire chose qui puisse arriver est que l'on choisisse d'utiliser le framework d'entité et ensuite d'écrire toutes les procédures stockées. Maintenant, on a une couche supplémentaire qui n'ajoute aucune valeur.

Jon Raynor
la source
100% d'accord avec le dernier paragraphe
Ewan
0

Avoir un besoin technique n'est pas le choix le plus probable. Les programmeurs préfèrent leurs outils et sont généralement plus à même de résoudre leurs problèmes avec eux. Mettre la logique dans un sproc sera l'exception. La dette technique et les futurs développeurs devant prendre du temps pour travailler avec une exception doivent être pris en considération. Il peut y avoir une amélioration des performances dans votre SGBDR particulier qui est simplement plus facile à implémenter dans un sproc ou peut-être même un autre objet db comme une vue indexée.

Il y aura des moments où vous aurez besoin de données d'une base de données et que vous ne pourrez tout simplement pas les obtenir à partir de votre code d'application. Dans de nombreuses situations de grande entreprise / entreprise, les besoins de l'entreprise peuvent dépasser la portée du service informatique. Les entreprises sont achetées et vendues et leurs applications vont et viennent avec elles. Les agences de régulation et les banques ne se soucient pas si vous ne pouvez pas créer votre application hautement évolutive et magnifiquement codée. Ils peuvent rendre la vie difficile à l'entreprise, vous devez donc le faire.

J'ai rencontré des situations où des applications tierces ou des outils d'écriture de rapports ne vous permettent pas d'accéder à votre code. Pas de code open source, pas d'API, pas d'interface web et pas de services. La seule chose qu'ils ont est leur propre outil spécial d'écriture de rapport qui ne fonctionne qu'avec des objets de base de données: tables, vues, sprocs, fonctions définies par l'utilisateur, etc. Vous mettez la logique partout où vous pouvez y accéder.

Si vous avez un DBA qui est très bon pour écrire des procédures stockées, vous pouvez tirer parti de ce talent dans certaines situations. Vous souhaiterez peut-être déclencher une sauvegarde à partir de votre application, car vous allez apporter une modification majeure aux données, alors pourquoi ne pas utiliser ce que votre dba utilise?

Certaines demandes ad hoc sont simplement plus faciles à écrire un proc jusqu'à ce que vous puissiez obtenir toutes les fonctionnalités de votre application. Nous détestons ça. Nous repoussons, mais le spectacle doit continuer.

JeffO
la source
0

Je déconseille fortement de placer une logique métier dans une procédure stockée. Cependant, il peut y avoir un cas (vous avez énuméré deux beaux exemples) où il est préférable d'y placer la logique d' accès aux données .

De manière générale, si vous êtes tenté d'utiliser des SP, c'est un signe (une odeur de code) laissant entendre que votre modèle de données n'est pas bien adapté à ses besoins.

Edit: Lorsque les développeurs me posent des questions sur la logique d'accès aux données / aux entreprises, je dis que la logique métier concerne le comportement et l'interaction des données, tandis que la logique d'accès aux données concerne la façon dont les données sont stockées et récupérées.

Par exemple: Dans votre modèle de domaine, vous pourriez avoir les entités "Student" et "Teacher", toutes deux dérivées de "Person". (Ne pas dire que c'est préférable, juste un exemple). Cela peut être stocké dans une base de données relationnelle sous la forme d'une, deux ou trois tables. Le choix dépend du nombre de propriétés qu'ils partagent et des exigences de performances en lecture / écriture.

Dans la logique métier, la façon dont ces entités sont stockées n'a pas d'importance. (ou s'ils résident dans un RDB). La logique d'accès aux données concerne leur stockage physique.

Donc, concernant la question d'origine: si une procédure stockée rend le stockage et la récupération de données plus efficaces (ou plus robustes), vous avez un cas. Si la procédure stockée vise simplement à imposer une règle que je valide quelle que soit la façon dont les données sont stockées, évitez-la. Cela rend votre code plus étroitement couplé à la base de données.

Guran
la source
2
Comment définiriez-vous la logique métier et la logique d' accès aux données ?
Amy Barrett
@AmyBarrett: Business Logic , Data Access Layer .
Robert Harvey
@RobertHarvey Merci pour les liens. La couche d'accès aux données est-elle identique à la logique d'accès aux données? Je demande car il ne semble pas y avoir beaucoup de logique réelle impliquée dans la couche d'accès aux données - juste de simples opérations CRUD.
Amy Barrett
@AmyBarrett: Eh bien, parfois vous écrivez des méthodes personnalisées dans la couche d'accès aux données, donc ce n'est pas toujours CRUD.
Robert Harvey
@RobertHarvey Mais ces méthodes personnalisées n'appartiendraient-elles pas à la couche logique métier?
Amy Barrett
-4

Je pense qu'il y a trois problèmes ici.

  1. Logique métier dans SQL est mauvaise. Même s'il s'exécute individuellement plus rapidement, il ne s'adapte pas.

  2. Traditionnellement, les SPROC doivent toujours être utilisés pour tous les accès aux données en tant que couche d'abstraction. Permettre à un DBA d'introduire des performances ou d'autres modifications de couche de données sans affecter les applications consommatrices.

  3. EF ne joue pas bien avec les sprocs. Vous perdrez beaucoup de «bonnes» fonctionnalités et gains de productivité en abandonnant la génération de requêtes dynamiques de Linq.

Donc, mon conseil général serait de

  • Utilisez des SPROC pour toutes les requêtes SQL,

  • N'y mettez pas de logique métier ni aucune sorte de boucle,

  • Ne EF utilisation.

Ewan
la source
Parce que tout le SQL s'exécute sur le serveur db, vous ne pouvez évoluer qu'avec des dbs supplémentaires plutôt qu'avec des boîtes de calcul supplémentaires.
Ewan
1
Je vois. Mais le point n ° 1 concerne uniquement un compromis entre deux problèmes de performances. Mais il y aura des moments où la solution SQL est une nette victoire en termes de performances, donc je ne vois pas comment elle peut être considérée comme catégoriquement "mauvaise" sur cette base.
1
disons que vous avez un webservice qui fait un calcul. Vous pouvez le faire en code ou en sql. disons que le sql est plus rapide dans un test tête à tête d'un seul calcul. Mais lorsque le service est au maximum, il est très bon marché et facile d'ajouter une deuxième, troisième, quatrième .. boîte exécutant le webservice mais difficile et coûteuse d'ajouter une deuxième base de données répliquée
Ewan
1
c'est un exemple d'un scénario particulier où SQL peut être une mauvaise conception en raison de l'évolutivité. Mais même dans ce cas, ce n'est pas clair: cela dépend du nombre d'utilisateurs prévu, du coût relatif de l'exécution du calcul dans la base de données par rapport à l'extérieur, etc. Bien sûr, vous avez raison dans certains cas, je ne pense pas que ce soit une règle universelle.
3
Ceci est un mauvais conseil, dans l' ensemble. Il y a beaucoup d'options pour l' accès aux données qui ont des avantages sur les procédures stockées et codage manuel réalisent aussi bien. Vous pouvez exécuter des sprocs directement depuis EF; en fait, vous pouvez exécuter n'importe quelle requête SQL directement depuis EF. Certaines logiques métier fonctionnent mieux sur un serveur de base de données, vous ne pouvez donc pas affirmer catégoriquement qu'elles y sont interdites. Les mappeurs relationnels d'objets sont un outil à 80%; ils n'ont jamais été conçus pour remplacer complètement vos processus d'accès aux données. Utilisez les procédures stockées pour ce à quoi elles sont destinées: les 20% qu'un ORM ne fait pas bien.
Robert Harvey