Je travaille sur un projet dans l'une des 3 plus grandes sociétés de conseil en informatique au monde, et un administrateur de base de données m'a dit que les procédures stockées d'État des meilleures pratiques de l'entreprise ne sont pas une "meilleure pratique". C'est tellement contraire à tout ce que j'ai appris.
Les procédures stockées vous offrent la réutilisation du code et l'encapsulation (deux piliers du développement logiciel), la sécurité (vous pouvez accorder/révoquer des autorisations sur un processus stocké individuel), vous protéger contre les attaques par injection SQL et également aider à la vitesse (bien que DBA ait déclaré que à partir de SQL Server 2008, même les requêtes SQL régulières sont compilées si elles sont exécutées suffisamment de fois).
Nous développons une application complexe en utilisant la méthodologie de développement logiciel Agile. Quelqu'un peut-il penser à de bonnes raisons pour lesquelles il ne voudrait pas utiliser les proc stockés? Je suppose que les administrateurs de base de données ne voulaient pas maintenir ces processus stockés, mais il semble y avoir beaucoup trop de négatifs pour justifier une telle décision de conception.
Dans mon expérience de travail sur de très grands projets, vous devez être très clair sur l'endroit où réside la logique métier. Si vous autorisez un environnement où les développeurs individuels peuvent mettre la logique métier dans la couche objet métier ou dans une procédure stockée comme ils l'entendent, une grande application devient TRÈS difficile à comprendre et à gérer.
Les procédures stockées sont idéales pour accélérer certaines opérations de base de données. Ma décision architecturale est de laisser toute la logique dans la couche métier de l'application et d'employer des procédures stockées de manière ciblée pour améliorer les performances lorsque l'analyse comparative l'indique.
Les procédures stockées vous offrent la réutilisation du code et l'encapsulation (deux piliers du développement logiciel),
Seulement si vous les utilisez correctement dans le contexte dans lequel ils sont censés être utilisés. La même affirmation peut être dite à propos des fonctions (en programmation structurée) ou des méthodes (en programmation orientée objet), et pourtant, nous voyons des fonctions 1K et des objets méga-ass.
Les artefacts ne vous procurent pas ces avantages. La bonne utilisation de ces artefacts est ce qui donne ces avantages.
la sécurité (vous pouvez accorder/révoquer des autorisations sur un processus individuel stocké),
Oui. C'est un bon point et l'une des principales raisons pour lesquelles j'aime les procédures stockées. Ils fournissent un contrôle d'accès à granularité plus fine que ce qui peut généralement être réalisé avec seulement des vues et des comptes d'utilisateurs.
vous protéger des attaques par injection SQL,
Ce n'est pas spécifique aux SP car vous pouvez atteindre le même niveau de protection avec des instructions SQL paramétrées et un nettoyage d'entrée. J'utiliserais des SP en plus de ceux-ci, cependant, pour "sécurité en profondeur" .
et également aider à la vitesse (bien que DBA ait déclaré qu'à partir de SQL Server 2008, même les requêtes SQL régulières sont compilées si elles sont exécutées suffisamment de fois).
C'est très spécifique au fournisseur de base de données, mais en général votre DBA a raison. Les instructions SQL (statiques ou paramétrées) sont compilées. Les SP vous aident si vous souhaitez/devez agréger et calculer des données que vous ne pouvez pas faire avec de simples instructions SQL, mais qui sont étroitement intégrées à SQL et ne garantissent pas l'aller-retour vers le serveur d'applications.
Un bon exemple est l'interrogation de données dans un curseur (ou curseurs) temporaire à partir duquel exécuter un autre SQL lui-même. Vous pouvez le faire par programme dans le serveur d'applications, ou vous pouvez enregistrer les allers-retours multiples en le faisant dans la base de données.
Cela ne devrait pas être la norme, cependant. Si vous avez beaucoup de ces cas, alors c'est un signe de mauvaise conception de la base de données (ou vous extrayez des données de schémas de base de données pas si compatibles entre les départements.)
Nous développons une application complexe en utilisant la méthodologie de développement logiciel Agile.
L'agilité concerne les processus de génie logiciel et la gestion des exigences, et non les technologies.
Quelqu'un peut-il penser à de bonnes raisons pour lesquelles il ne voudrait pas utiliser les proc stockés?
La question est fausse et équivaut à demander "y a-t-il de bonnes raisons de ne pas utiliser GOTO"? Je suis plus proche de Niklaus Wirth que de Dijkstra sur ce sujet. Je peux comprendre d'où vient le sentiment de Dijkstra, mais je ne pense pas qu'il soit applicable à 100% dans tous les cas. Même chose avec les procs de magasin et toute technologie.
Un outil est bon lorsqu'il est bien utilisé pour l'usage auquel il est destiné et lorsqu'il est le meilleur outil pour la tâche particulière. L'utiliser autrement n'est pas une indication que l'outil est mauvais, mais que le porteur ne sait pas ce qu'il fait.
La bonne question est "quel type de modèles d'utilisation de procédures stockées doit être évité." Ou, "dans quelles conditions dois-je (ou ne dois-je pas) utiliser des procédures stockées ". Chercher des raisons pas pour utiliser une technologie revient simplement à rejeter la faute sur l'outil au lieu de placer la responsabilité d'ingénierie à sa juste place - chez l'ingénieur.
En d'autres termes, c'est une dérobade ou une déclaration d'ignorance.
Je suppose que les administrateurs de base de données ne voulaient pas maintenir ces processus stockés, mais il semble y avoir beaucoup trop de négatifs pour justifier une telle décision de conception.
Ce qu'ils font alors, c'est projeter les résultats de leurs mauvaises décisions d'ingénierie sur les outils qu'ils ont mal utilisés.
D'après mon expérience, à Rome, faites comme les Romains .
Ne le combattez pas. Si les employés de votre entreprise souhaitent étiqueter les processus de magasin comme une mauvaise pratique, laissez-les. Sachez cependant que cela peut être un drapeau rouge dans leurs pratiques d'ingénierie.
L'étiquetage typique des choses comme mauvaise pratique est généralement fait dans les organisations avec des tonnes de programmeurs incompétents. En mettant sur liste noire certaines choses, l'organisation essaie de limiter les dommages infligés en interne par leur propre incompétence. Je te chie pas.
Les généralisations sont la mère de tous les ratés. Dire que les proc stockés (ou tout type de technologie) sont une mauvaise pratique, c'est une généralisation. Les généralisations sont des dérogations pour les incompétents. Les ingénieurs ne travaillent pas avec des généralisations flagrantes. Ils effectuent des analyses au cas par cas, analysent les compromis et exécutent les décisions et les solutions d'ingénierie en fonction des faits, dans le contexte dans lequel ils sont censés résoudre un problème.
Les bons ingénieurs ne qualifient pas les choses de mauvaises pratiques de manière aussi généralisée. Ils examinent le problème, sélectionnent l'outil approprié, font des compromis. En d'autres termes, ils font de l'ingénierie.
N'y mettez pas une logique complexe au-delà de la collecte de données (et peut-être de certaines transformations). Il est correct de mettre une logique de massage des données dedans, ou de agréger le résultat de plusieurs requêtes avec eux. Mais c'est tout. Tout ce qui est au-delà de cela pourrait être considéré comme une logique métier qui devrait résider ailleurs.
Ne les utilisez pas comme votre seul mécanisme de défense contre l'injection SQL. Vous les laissez là au cas où quelque chose de mauvais leur arriverait, mais il devrait y avoir une multitude de logiques défensives devant eux - validation/nettoyage côté client, validation/nettoyage côté serveur, éventuellement transformation en types qui ont du sens dans votre modèle de domaine, et enfin être passé aux instructions paramétrées (qui peuvent être des instructions SQL paramétrées ou des procs stockés paramétrés.)
Ne faites pas des bases de données le seul endroit contenant vos procs de magasin. Vos procs de magasin doivent être traités comme vous traitez votre C # ou Java code source. Autrement dit, contrôlez à la source la définition textuelle de vos procs de magasin. Les gens prétendent que les procs de magasin ne peuvent pas être contrôlés par la source - bullcrap, ils ne savent tout simplement pas de quoi ils parlent.
Votre application nécessite des données qui doivent être transposées ou agrégées à partir de plusieurs requêtes ou vues. Vous pouvez décharger ces données de l'application dans la base de données. Ici, vous devez faire une analyse des performances car a) les moteurs de base de données sont plus efficaces que les serveurs d'applications pour faire ces choses, mais b) les serveurs d'applications sont (parfois) plus faciles à mettre à l'échelle horizontalement.
Contrôle d'accès à grain fin. Vous ne voulez pas qu'un idiot exécute des jointures cartésiennes dans votre base de données, mais vous ne pouvez pas simplement interdire aux gens d'exécuter des instructions SQL arbitraires comme ça Soit. Une solution typique consiste à autoriser des instructions SQL arbitraires dans les environnements de développement et UAT, tout en les interdisant dans les environnements systest et de production. Toute déclaration qui doit arriver à systest ou à la production entre dans une procédure de magasin, révisée par les développeurs et dbas.
Tout besoin valide d'exécuter une instruction SQL pas dans un processus de magasin passe par un nom d'utilisateur/compte et un pool de connexions différents (avec une utilisation hautement surveillée et découragée.)
Que vous exécutiez cela sur la base de données en tant que proc de magasin ou sur votre serveur d'applications dépend de l'analyse de compromis que vous, en tant qu'ingénieur, devez faire. Les deux options doivent être analysées et justifiées par un certain type d'analyse. Aller d'une manière ou d'une autre en accusant simplement l'autre alternative de "mauvaise pratique", c'est juste une erreur technique.
Que cela devienne une solution permanente ou non, cela est spécifique aux contraintes observées à ce moment particulier.
J'espère que cela aide.
La raison en est que s'appuyer sur une couche de procédures stockées limite la portabilité et vous lie à une certaine base de données. Les coûts de maintenance supplémentaires sont également cités comme raison. Je voulais également commenter ce point que vous avez fait:
(procédures stockées) vous protègent contre les attaques par injection SQL
C'est en fait la requête paramétrée qui vous protège, ce que vous pouvez facilement faire dans la requête SQL en texte brut.
Certaines des raisons pour lesquelles j'accepte les proc stockés ne sont pas une bonne pratique.
Les procédures stockées vous offrent la réutilisation du code et l'encapsulation (deux piliers du développement logiciel),
Oui, mais au prix de pouvoir atteindre d'autres objectifs de conception agile. Ils sont plus difficiles à entretenir, d'une part. Si le projet sur lequel je suis est une indication, vous vous retrouverez probablement avec plusieurs SP incompatibles qui font essentiellement le même travail, sans aucun avantage.
vous protéger des attaques par injection SQL,
Non, ils ne pas. Je ne peux même pas commencer à deviner d'où cette idée pourrait provenir, comme je l'entends souvent dire, et ce n'est tout simplement pas vrai. Cela peut atténuer certains types d'attaques par injection SQL, mais si vous n'utilisez pas de requêtes paramétrées en premier lieu, cela n'aura pas d'importance. Je peux encore '; Comptes DROP TABLE; -
et également aider à la vitesse (bien que DBA ait déclaré qu'à partir de SQL Server 2008, même les requêtes SQL régulières sont compilées si elles sont exécutées suffisamment de fois).
Ils sont également généralement compilés lorsque vous utilisez des instructions préparées et paramétrées (au moins avec plusieurs des bases de données que j'ai utilisées). Au moment où votre application commence à exécuter la requête (ou en particulier lorsque vous exécutez plusieurs fois la même requête préparée), tout avantage en termes de performances que vous pensez que votre SP possède) est totalement théorique.
La raison niquement d'utiliser une procédure stockée, à mon humble avis, est lorsque vous devez effectuer une requête complexe à plusieurs étapes qui tire de plusieurs sources assemblées. Les SP ne doivent pas contenir de logique de décision de bas niveau, et ils doivent jamais simplement encapsuler une requête autrement simple. Il n'y a aucun avantage et seulement de nombreux inconvénients.
Écoutez votre DBA. Il sait ce qui se passe.
Les trois sociétés pour lesquelles je travaille ont utilisé des procédures stockées pour leur logique d'application avec SQL Server. Je n'ai pas vraiment vu les choses dans l'autre sens. Mais pour moi, c'est un gros gâchis. Il n'y a généralement pas de très bonnes installations de gestion des erreurs ou des installations de réutilisation de code avec des procédures stockées.
Supposons que vous ayez une procédure stockée qui renvoie un ensemble de données que vous souhaitez utiliser, comment pouvez-vous l'utiliser dans les futures procédures stockées? Les mécanismes sur SQL Server pour cela ne sont pas très bons. EXEC INTO ... ne fonctionne qu'à un ou deux niveaux) d'imbrication (j'oublie maintenant). Ou vous devez prédéfinir une table de travail et la faire incruster. Ou vous devez pré-créer une table temporaire et demander à la procédure de la remplir. Mais que se passe-t-il si deux personnes appellent une table temporaire la même chose dans deux procédures différentes qu'elles n'ont jamais prévu d'utiliser en même temps? Dans n'importe quel langage de programmation normal, vous pouvez simplement renvoyer un tableau à partir d'une fonction ou pointer vers un objet/une structure globale partagée entre eux (sauf pour les langages fonctionnels où vous retourneriez la structure de données au lieu de simplement changer une structure globale ... )
Et la réutilisation du code? Si vous commencez à mettre des expressions courantes dans des FDU (ou des sous-requêtes encore pires), vous ralentirez le code. Vous ne pouvez pas appeler une procédure stockée pour effectuer un calcul pour une colonne (sauf si vous utilisez un curseur, passez les valeurs de la colonne une par une, puis mettez à jour votre table/ensemble de données d'une manière ou d'une autre). Donc, fondamentalement, pour obtenir les meilleures performances, vous devez couper/coller des expressions communes partout, ce qui est un cauchemar de maintenance ... Avec un langage de programmation, vous pouvez créer une fonction pour générer le SQL commun, puis l'appeler de partout lors de la construction la chaîne SQL. Ensuite, si vous avez besoin d'ajuster la formule, vous pouvez effectuer le changement en un seul endroit ...
Que diriez-vous de la gestion des erreurs? SQL Server contient de nombreuses erreurs qui empêchent immédiatement l'exécution de la procédure stockée et certaines qui forcent même une déconnexion. Depuis 2005, il y a try/catch mais il y a encore un certain nombre d'erreurs qui ne peuvent pas être détectées. De plus, la même chose se produit avec la duplication de code sur le code de gestion des erreurs et vous ne pouvez vraiment pas passer des exceptions aussi facilement ou les propulser à des niveaux supérieurs aussi facilement que la plupart des langages de programmation .....
Aussi juste de la vitesse. De nombreuses opérations sur les ensembles de données ne sont pas orientées SET. Si vous essayez de faire des trucs orientés lignes, soit vous allez utiliser un curseur, soit vous allez utiliser un "curseur" (lorsque les développeurs interrogent souvent chaque ligne une par une et stockent le contenu dans des variables @ comme un curseur. ..Même si c'est souvent plus lent qu'un curseur FORWARD_ONLY). Avec SQL Server 2000, j'avais quelque chose qui fonctionnait pendant 1 heure avant de le tuer. J'ai réécrit ce code en Perl et il s'est terminé en 20 minutes. Lorsqu'un langage de script 20-80x plus lent que C fume SQL dans les performances, vous n'avez certainement aucune activité d'écriture orientée ligne en SQL.
Désormais, SQL Server a une intégration CLR et beaucoup de ces problèmes disparaissent si vous utilisez une procédure stockée CLR. Mais de nombreux administrateurs de base de données ne savent pas comment écrire des programmes .NET ou désactiver le CLR en raison de problèmes de sécurité et s'en tenir à Transact SQL .... De plus, même avec les CLR, vous avez toujours des problèmes de partage de données entre plusieurs procédures de manière efficace .
En général, la base de données est la chose la plus difficile à mettre à l'échelle. Si toute votre logique métier se trouve dans la base de données, alors lorsque la base de données devient trop lente, vous allez avoir des problèmes. Si vous avez une couche métier, vous pouvez simplement ajouter plus de cache et plus de serveurs d'entreprise pour augmenter les performances. Traditionnellement, un autre serveur pour installer Windows/Linux et exécuter .NET/Java est beaucoup moins cher que d'acheter un autre serveur de base de données et d'octroyer plus de licences SQL Server. Cependant, SQL Server prend désormais davantage en charge le clustering, à l'origine il n'en avait pas vraiment. Donc, si vous avez beaucoup d'argent, vous pouvez ajouter un cluster ou même envoyer des journaux pour faire plusieurs copies en lecture seule. Mais dans l'ensemble, cela coûtera beaucoup plus que d'avoir une écriture derrière le cache ou quelque chose.
Regardez également les fonctionnalités de Transact-SQL. Manipulation de chaînes? Je prendrai les classes Java String Class/Tokenizer/Scanner/Regex tous les jours. Tables de hachage/Listes liées/Etc. Je prendrai les Java Framework de collection, etc ... Et la même chose pour .NET ... C # et Java sont des langages beaucoup plus évolués que Transact SQL ... Le codage diabolique avec Transact-SQL me rend jaloux de C ...
De plus, les procédures stockées sont plus efficaces pour travailler avec un grand ensemble de données et appliquer plusieurs requêtes/critères pour le réduire avant de le retourner à la couche métier. Si vous devez envoyer un tas d'énormes ensembles de données à l'application cliente et décomposer les données sur le client, cela sera beaucoup plus inefficace que de faire tout le travail sur le serveur.
Les procédures stockées sont également bonnes pour la sécurité. Vous pouvez couper tous les accès aux tables sous-jacentes et autoriser uniquement l'accès via les procédures stockées. Avec certaines techniques modernes comme XML, vous pouvez avoir des procédures stockées qui effectuent des mises à jour par lots. Ensuite, tous les accès sont contrôlés via les procédures stockées de sorte que tant qu'elles sont sécurisées/correctes, les données peuvent avoir plus d'intégrité.
L'argument d'injection SQL ne s'applique plus vraiment puisque nous avons des requêtes paramétrées du côté du langage de programmation. Même avant les requêtes paramétrées, un petit remplacement ("'", "' '") fonctionnait également la plupart du temps (bien qu'il y ait encore des astuces à utiliser pour dépasser la fin de la chaîne pour obtenir ce que vous voulez).
Dans l'ensemble, je pense que SQL et Transact SQL sont d'excellents langages pour interroger/mettre à jour des données. Mais pour coder n'importe quel type de logique, faire de la manipulation de chaînes (ou diable manipulation de fichiers .... vous seriez surpris de ce que vous pouvez faire avec xp_cmdshell ....) s'il vous plaît non. J'espère trouver un futur endroit qui n'utilisera pas principalement de procédures stockées. Du point de vue de la maintenabilité du code, ils sont un cauchemar. De plus, que se passe-t-il si vous souhaitez changer de plate-forme (bien que vraiment si vous avez payé pour Oracle/DB2/Sybase/Sql Server/etc., vous pourriez tout aussi bien en tirer le meilleur parti en utilisant toutes les extensions propriétaires que vous pouvez qui vous aident. ..).
De manière surprenante, la logique métier n'est pas toujours la même. Dans le monde idéal, vous mettriez toute la logique dans les procédures stockées et la partageriez entre les applications. Mais très souvent, la logique diffère en fonction des applications et vos procédures stockées finissent par devenir des monolithes trop complexes que les gens ont peur de changer et ne comprennent pas toutes les implications de. Alors qu'avec un bon langage orienté objet, vous pouvez coder une couche d'accès aux données qui a une interface/des crochets standard que chaque application peut remplacer à leurs propres besoins.
C'était la ligne officielle lorsque je travaillais pour l'un des Big Five il y a quelques années. Le raisonnement était que puisque les SP sont liés à des implémentations particulières (PL/SQL vs T/SQL vs ...), ils limitent inutilement les choix technologiques.
Ayant vécu la migration d'un grand système de T/SQL vers PL/SQL, je peux comprendre l'argument. Je pense que c'est un peu un canard cependant - combien d'endroits vraiment passer d'une base de données à une autre sur un coup de tête?
Comment version des procédures stockées sur le serveur?
Si vous redéployez des procédures stockées sur le serveur à partir du contrôle de version, vous supprimez le plan d'exécution stocké.
Les procédures stockées ne doivent pas être modifiables directement sur le serveur, sinon comment savoir ce qui fonctionne vraiment maintenant? Si ce n'est pas le cas, l'outil de déploiement doit avoir accès pour écrire des procédures stockées dans la base de données. Vous devez déployer sur chaque build (le plan d'exécution peut devoir être différent)
Bien que les procédures stockées ne soient pas portables, ni SQL en général (jamais vu la gestion de date Oracle - uggghhh).
Donc, si vous voulez la portabilité, créez une API d'accès aux données internes. Vous pouvez appeler cela comme des appels de fonction, et en interne, vous pouvez intégrer dans le jargon que vous voulez, avec des requêtes paramétrées, et il peut être contrôlé par la version.
C'est tellement contraire à tout ce que j'ai appris.
Vous devrez peut-être en sortir plus. [sourire] Sérieusement, les proc stockés sont en déclin depuis au moins 10 ans. Presque depuis que n-tier a remplacé client-serveur. Le déclin n'a été accéléré que par l'adoption de langages OO comme Java, C #, Python, etc.
Cela ne veut pas dire que les proc stockés n'ont toujours pas leurs partisans et leurs défenseurs - mais c'est une discussion et un débat de longue date. Ce n'est pas nouveau et continuera probablement pendant un certain temps; OMI, les adversaires des proc stockés gagnent clairement.
Les procédures stockées vous offrent la réutilisation du code et l'encapsulation (deux piliers du développement logiciel)
Très vrai. Mais, il en va de même pour une couche décemment architecturée OO.
sécurité (vous pouvez accorder/révoquer des autorisations sur un processus stocké individuel)
Bien que vous puissiez le faire, peu le font en raison des graves limitations. La sécurité au niveau de la base de données n'est pas suffisamment granulaire pour prendre des décisions contextuelles. En raison des performances et des frais généraux de gestion, il est inhabituel d'avoir des connexions par utilisateur également - vous avez donc toujours besoin d'un certain niveau d'autorisation dans le code de votre application. Vous pouvez utiliser des connexions basées sur les rôles, mais vous devrez les créer pour de nouveaux rôles, conserver le rôle que vous utilisez, changer de connexion pour que le travail au niveau système fonctionne comme la journalisation, etc. Et, au final, si votre application appartient - tout comme votre connexion à la base de données.
vous protéger contre les attaques par injection SQL
Pas plus que de faire des requêtes paramétrées. Ce que vous devez faire de toute façon.
et également aider à la vitesse (bien que DBA ait déclaré qu'à partir de SQL Server 2008, même les requêtes SQL régulières sont compilées si elles sont exécutées suffisamment de fois).
Je pense que cela a commencé dans MSSQL 7 ou 2000. Il y a eu beaucoup de débats, de mesures et de désinformation sur les performances stockées proc vs inline SQL - je les regroupe sous YAGNI. Et, si vous en avez besoin, testez.
Nous développons une application complexe en utilisant la méthodologie de développement logiciel Agile. Quelqu'un peut-il penser à de bonnes raisons pour lesquelles il ne voudrait pas utiliser les proc stockés?
Je ne peux pas penser à beaucoup de raisons pour lesquelles vous voudriez vouloir. Java/C #/tout 3e GL sont tous beaucoup plus capables que T-SQL pour l'encapsulation, la réutilisation et la felxibilité, etc. La plupart sont gratuits étant donné un ORM à moitié décent.
En outre, étant donné les conseils de "distribuer au besoin, mais pas plus" - je pense que la charge de la preuve de nos jours incombe à SP défenseurs. Une raison courante pour aller lourdement stocké est que T- SQL est plus facile que OO, et la boutique a de meilleurs développeurs T-SQL que OO. Ou, que le DBA s'arrête à la couche de base de données, et les proc stockés sont l'interface entre le dev et le DBA. Ou, vous expédiez un semi-personnalisé Le produit et les proc stockés peuvent être personnalisés par l'utilisateur. En l'absence de telles considérations, je pense que la valeur par défaut pour tout projet Agile SW de nos jours sera ORM.
Compte tenu de tous les cas ci-dessus, je voudrais en ajouter un de plus. Le choix de SP peut aussi dépendre du choix des personnes.
Personnellement, je me sens frustré lorsque les gens mettent une logique très complexe dans SP et je crois que tel SP est très complexe à maintenir et à déboguer. Même dans de nombreux cas, le développeur lui-même est confronté problème lors du débogage dans le code derrière (disons partie du langage) est beaucoup plus facile que dans SP.
SP ne doit être utilisé que pour des opérations simples. Eh bien, c'est mon choix.
Je veux couvrir à la fois certains problèmes et les problèmes avec les proc stockés. Nous les utilisons largement avec LedgerSMB , et notre règle est, avec quelques extensions très spécifiques, "si c'est une requête, faites-en un proc stocké."
Notre raison pour cela était de faciliter la réutilisation des requêtes multilingues. Il n'y a pas de meilleure façon de le faire honnêtement.
En fin de compte, la question est toujours sur les détails. Bien utilisées, les procédures stockées rendent les choses beaucoup plus faciles et mal utilisées, elles rendent les choses beaucoup plus difficiles.
Donc, du côté con.
Comme elles sont traditionnellement utilisées, les procédures stockées sont fragiles. Utilisés seuls, ils créent la possibilité d'ajouter des bogues à votre code dans des endroits auxquels vous ne vous attendiez pas pour une raison autre que celle de la syntaxe de l'appel. Utilisé seul, c'est un peu un problème. Il y a beaucoup trop de cohésion entre les couches et cela pose des problèmes.
Oui, il est possible d'avoir une injection SQL intra-sproc si vous effectuez un SQL dynamique. C'est une mauvaise chose d'être trop confiant dans ce domaine, et par conséquent, il faut avoir une expérience significative en matière de sécurité dans ce domaine.
Les modifications des interfaces sont quelque peu problématiques avec les procédures stockées pour la raison n ° 1 ci-dessus, mais cela peut devenir un très grand cauchemar si un grand nombre d'applications clientes sont impliquées.
Ce qui précède est assez difficile à nier. Ils arrivent. Tout le monde, pro-SP et anti-SP a probablement eu des histoires d'horreur à ce sujet. Les problèmes ne sont pas insolubles, mais si vous n'y faites pas attention, vous ne pouvez pas les résoudre (dans LedgerSMB, nous utilisons un localisateur de services pour créer dynamiquement SP appels au moment de l'exécution, en évitant Si nous ne sommes que PostgreSQL, quelque chose de similaire pourrait être fait pour d'autres db).
Sur les points positifs. En supposant que vous puissiez résoudre les problèmes ci-dessus, vous obtenez:
La possibilité d'une clarté accrue dans les opérations d'ensemble. Cela est particulièrement vrai si votre requête est très volumineuse ou très flexible. Cela conduit également à une testabilité améliorée.
Si un localisateur de services travaille déjà dans ce domaine, je trouve que les procédures stockées accélèrent le rythme de développement car elles libèrent le développeur d'applications des problèmes de base de données et vice versa. Cela a quelques difficultés à bien faire, mais ce n'est pas si difficile à faire.
Réutilisation des requêtes.
Oh et quelques choses que vous ne devriez presque jamais faire dans un SP:
logique non transactionnelle. Vous avez envoyé l'e-mail indiquant que la commande a été expédiée, mais la transaction a été annulée ... ou maintenant vous attendez de continuer pour que le serveur de messagerie se connecte ... ou pire, vous annulez votre transaction simplement parce que vous ne pouvez pas atteindre le serveur de messagerie ....
beaucoup de petites requêtes reliées les unes aux autres, saupoudrées de logique procédurale ...
Il est très difficile de changer de marque de base de données et d'utiliser les mêmes procédures stockées.
Votre équipe n'a pas non plus de DBA et personne d'autre ne veut rien avoir à faire avec sql.
Ce n'est rien de plus qu'un concours de pisse programmeur contre DBA.
Pour qui travaillez-vous?
La réponse peut dépendre de qui vous êtes employé, du cabinet de conseil ou de l'entreprise elle-même. Ce qui est le mieux pour une entreprise n'est souvent pas le meilleur pour une firme de consultants ou un autre fournisseur de logiciels. par exemple. Une entreprise intelligente souhaite avoir un avantage permanent sur ses concurrents. En revanche, un éditeur de logiciels souhaite pouvoir colporter la même solution à toutes les entreprises d'une industrie particulière, pour le moindre coût. S'ils y parviennent, il n'y aura aucun avantage concurrentiel net pour le client.
Dans ce cas particulier, les applications vont et viennent, mais très souvent, la base de données d'entreprise dure éternellement. L'une des principales fonctions d'un SGBDR est d'empêcher les données indésirables de pénétrer dans la base de données. Cela peut impliquer des procédures stockées. Si la logique est bonne et qu'il est très peu probable qu'elle change d'une année à l'autre, pourquoi ne devrait-elle pas figurer dans la base de données, en la maintenant cohérente en interne, quelle que soit l'application écrite pour utiliser la base de données? Des années plus tard, quelqu'un aura une question qu'il voudra poser à la base de données et il sera possible de répondre si le courrier indésirable n'a pas pu entrer dans la base de données.
Alors peut-être que cela a quelque chose à voir avec le fait que votre DBA travaille pour une société de conseil. Plus ils peuvent rendre leur code portable, plus ils peuvent réutiliser le code d'un client à l'autre. Plus ils peuvent lier de logique dans leur application, plus l'entreprise est attachée au fournisseur. S'ils laissent un gros gâchis dans le processus, ils seront payés pour le nettoyer, ou ne reverront jamais le gâchis. De toute façon, c'est une victoire pour eux.
Pour (beaucoup) plus de discussion des deux côtés de la clôture, lisez la discussion sur coding horror . FWIW Je me penche du côté de ceux qui plaident pour les PS.
Programmation en solo, je ne résiste pas écriture de procédures stockées.
J'utilise principalement MySQL. Je n'ai jamais utilisé de bases de données orientées objet comme PostGreSQL, mais ce que je peux faire avec les SP dans MySQL, c'est un peu la structure de la table. Les SP me permettent de concevoir ces actions primitives, dont les entrées et sorties ne changeront pas, même si la base de données en dessous change change.
J'ai donc une procédure appelée logIn
. Lorsque vous vous connectez, vous passez toujours simplement username
et password
. Le résultat renvoyé est l'entier userId
.
Lorsque logIn
est une procédure stockée, je peux maintenant ajouter un travail supplémentaire à effectuer lors de la connexion qui se produit en même temps que la connexion initiale. Je trouve une série d'instructions SQL avec une logique intégrée dans une procédure stockée - plus facile à écrire que la série (environnement d'appel FETCH) -> (obtenir le résultat) -> (environnement d'appel FETCH) que vous devez faire lorsque vous écrivez du côté de votre serveur logique.
C'est toujours une source de problèmes que la logique métier soit répartie entre différentes couches, en utilisant différents langages de programmation. Tracer un bogue ou implémenter un changement est beaucoup plus difficile lorsque vous devez basculer entre les mondes.
Cela dit, je connais des entreprises qui réussissent assez bien en mettant tous la logique métier dans des packages PL/SQL vivant dans la base de données. Ce ne sont pas de très grandes applications, mais pas banales non plus; disons 20K-100K LOC. (PL/SQL est mieux adapté à ce type de système que T-SQL, donc si vous ne connaissez que T-SQL, vous secouez probablement la tête en ne croyant pas maintenant ...)
Ceci est un autre point non encore mentionné:
Les outils de génération de code et les outils d'ingénierie inverse ne peuvent pas vraiment faire face aux procédures stockées. L'outil ne peut généralement pas dire ce que fait le proc. Le proc renvoie-t-il un jeu de résultats? Plusieurs jeux de résultats? Récupère-t-il ses jeux de résultats dans plusieurs tables et tables temporaires? Le proc est-il simplement une instruction de mise à jour encapsulée et ne renvoie rien? Renvoie-t-il un jeu de résultats, une valeur de retour et une "sortie console"?
Donc, si vous souhaitez utiliser un outil pour créer automatiquement une couche DTO et DAO d'objet de transfert de données (comme le fait le "constructeur de services" de liferay), vous ne pouvez pas le faire facilement.
De plus, les ORM comme Hibernate ne peuvent pas vraiment fonctionner correctement lorsque la source de données est un SP. L'accès aux données est en lecture seule au mieux.
OMI ça dépend. Les procédures stockées ont leur place, mais elles ne sont pas une bonne pratique et ne doivent pas être évitées à tout prix. Un développeur intelligent sait comment évaluer correctement une situation donnée et déterminer si une procédure stockée est la réponse. Personnellement, je suis un fan de l'utilisation d'un ORM quelconque (même de base comme Linq to Sql brut) plutôt que de procédures stockées, sauf peut-être pour des rapports prédéfinis ou similaires, mais encore une fois, c'est vraiment au cas par cas.
Je suis d'accord avec Mark que la communauté s'est vraiment éloignée des procédures stockées depuis un certain temps maintenant. Bien que bon nombre des points soulevés par l'affiche originale sur la raison pour laquelle nous souhaitions utiliser des SP étaient valides à un moment donné, cela fait un bon bout de temps et, comme l'a dit une autre affiche, l'environnement a changé. Par exemple, je me souviens d'un argument pour utiliser les SP `` dans la journée '' était les gains de performances obtenus parce que leurs plans d'exécution étaient `` précompilés '' tandis que le SQL dynamique de notre code devait être `` recompilé '' à chaque exécution. Ce n'est plus le cas car les principales bases de données ont changé, améliorées, adaptées, etc.
Cela dit, nous utilisons des SP sur mon projet actuel. La raison en est tout simplement parce que nous créons de nouvelles applications au-dessus d'une base de données existante qui prend toujours en charge les applications héritées. Par conséquent, il est très difficile d'apporter des modifications au schéma jusqu'à ce que nous désactivions les applications héritées. Nous avons pris la décision consciente de concevoir nos nouvelles applications en fonction du comportement et des règles requises pour l'application et d'utiliser les SP pour interfacer temporairement avec la base de données comme nous le souhaiterions et permettre aux SP de s'adapter au SQL existant . Cela revient au point d'une affiche précédente que les SP facilitent les modifications au niveau de la base de données sans nécessiter de modifications du code d'application. L'utilisation de SP comme implémentation du modèle d'adaptateur est certainement logique pour moi (en particulier compte tenu de mon projet actuel), et peut être le seul argument que je puisse vraiment voir POUR leur utilisation aujourd'hui.
Fwiw, nous avons l'intention de supprimer les SP lorsque le schéma est mis à jour. Mais, comme pour tout le reste dans le développement de l'entreprise, nous verrons si cela se produit! [sourire]
Je tiens également à souligner que les procédures stockées utilisent du temps processeur sur le serveur. Pas beaucoup, mais certains. Une partie du travail effectué dans la procédure de travail pourrait être effectuée dans l'application. Il est plus facile de mettre à l'échelle la couche d'application que la couche de données.
Je voulais juste faire un aperçu concis de la façon dont je recommanderais d'utiliser des procédures stockées. Je ne pense pas que ce soit une mauvaise pratique du tout, et comme d'autres l'ont dit, ils devraient être utilisés dans les situations appropriées.
Je peux voir des problèmes où l'écriture de procédures pour différentes applications peut devenir source de confusion dans les fonctionnalités et séparer la logique métier de l'application et entraîner une désorganisation et une restriction de la base de données.
Par conséquent, j'utiliserais une procédure stockée dans des tâches relationnelles orientées données spécifiques à la base de données. En d'autres termes, s'il existe une logique utilisée pour les opérations de base de données qui est cohérente avec les données de n'importe quelle application, une procédure stockée peut être utilisée pour conserver les données stockées de manière cohérente (logique). Je pense que de bons exemples de cela sont: journalisation cohérente, maintenance cohérente, travail avec des informations sensibles, etc.
Je pense que les autres tâches qui consistent à manipuler les données pour répondre aux besoins de l'application et qui suivent le modèle de données solide de la base de données devraient ensuite être stockées dans une autre couche contenant la logique métier. En bref, la manipulation de données spécifiques à la base de données pour la cohérence pourrait utiliser des procédures stockées, où la cohérence s'étend au-delà du modèle de schéma d'intégrité de la base de données.