J'ai travaillé sur certains projets où la majeure partie de la logique métier était implémentée dans la base de données (principalement via des procédures stockées). De l'autre côté, certains collègues programmeurs m'ont dit que c'était une mauvaise pratique ("Les bases de données sont là pour stocker des données. Les applications sont là pour faire le reste").
Laquelle de ces approches est généralement la meilleure?
Les avantages de la mise en œuvre de la logique métier dans la base de données à laquelle je peux penser sont:
- Centralisation de la logique métier;
- Indépendance du type d'application, du langage de programmation, du système d'exploitation, etc.
- Les bases de données sont moins sujettes à la migration technologique ou aux grands refactorisations (selon les informations dont je dispose)
- Aucune retouche sur la migration de la technologie d'application (par exemple: .NET vers Java, Perl vers Python, etc.).
Les inconvénients:
- Le langage SQL est moins productif et plus complexe pour la programmation de logique d’entreprise, en raison du manque de bibliothèques et de constructions de langage, ce qui en fait l’offre de langages la plus orientée application;
- Plus difficile (si possible) la réutilisation du code dans les bibliothèques;
- IDE moins productifs.
Remarque: les bases de données dont je parle sont des bases de données relationnelles populaires telles que SQL Server, Oracle, MySql, etc.
Merci!
Réponses:
La logique métier ne va pas dans la base de données
Si nous parlons d'applications multi-niveaux, il semble assez clair que la logique métier, le type de renseignement qui gère une entreprise particulière, appartient à la couche de logique applicative, pas à la couche d'accès aux données.
Les bases de données font très bien certaines choses:
Maintenant, bien sûr, vous pouvez codifier toutes sortes d'éléments dans une base de données concernant vos préoccupations commerciales, tels que les taux d'imposition, les remises, les codes d'opération, les catégories, etc. Mais l' action entreprise sur ces données n'est généralement pas codée dans la base de données, pour toutes sortes de raisons déjà mentionnées par d'autres, bien qu'une action puisse être choisie dans la base de données et exécutée ailleurs.
Et bien sûr, certaines choses peuvent être exécutées dans une base de données pour des raisons de performances et pour d'autres raisons:
Naturellement, rien n'est gravé dans la pierre. Les procédures stockées conviennent à un large éventail de tâches simplement parce qu'elles résident sur le serveur de base de données et présentent certains avantages et forces.
Procédures stockées partout
Il y a une certaine attirance à coder toutes vos tâches de stockage, de gestion et de récupération de données dans des procédures stockées, et à consommer simplement les services de données résultants. Vous bénéficierez certainement des optimisations maximales possibles en termes de performances et de sécurité que le serveur de base de données pourrait fournir, et ce n'est pas une mince affaire.
Mais que risquez-vous?
Et bien sûr, si vous avez besoin d’un service Web (et c’est probablement là que tout se passe, de toute façon), vous devrez toujours le construire.
Alors, quelle est la pratique typique?
Je dirais qu'une approche moderne typique consiste à utiliser un mappeur relationnel-objet (tel que Entity Framework) pour créer des classes qui modélisent vos tables. Vous pouvez ensuite parler à votre base de données via un référentiel qui renvoie des collections d'objets, une situation très familière à tout développeur de logiciel compétent. L'ORM génère dynamiquement du code SQL correspondant à votre modèle de données et aux informations demandées, que le serveur de base de données traite ensuite pour renvoyer les résultats de la requête.
Comment ça marche? Très bien et beaucoup plus rapidement que l’écriture de procédures stockées et de vues. Cela couvre généralement environ 80% de vos besoins d’accès aux données, principalement CRUD. Qu'est-ce qui couvre l'autre 20%? Vous l'avez deviné: les procédures stockées, que tous les principaux ORM prennent en charge directement.
Pouvez-vous écrire un générateur de code faisant la même chose qu'un ORM, mais avec des procédures stockées? Sûr que vous pouvez. Mais les ORM sont généralement indépendants des fournisseurs, bien compris de tous et mieux supportés.
la source
Je suis un fervent partisan de la conservation de la base de données autant que possible de la logique commerciale. Cependant, en tant que développeur de performances de mon entreprise, j'apprécie qu'il est parfois nécessaire d'obtenir de bonnes performances. Mais je pense que cela est nécessaire beaucoup moins souvent que ne le prétendent les gens.
Je conteste vos avantages et vos inconvénients.
Vous prétendez que cela centralise votre logique métier. Au contraire, je pense que cela le décentralise. Dans un produit sur lequel je travaille actuellement, nous utilisons des procédures stockées pour une grande partie de notre logique métier. Bon nombre de nos problèmes de performances proviennent de l'appel répété de fonctions. Par exemple
Le problème avec cette approche est qu’elle (dans certains cas, cela est faux) force la base de données à exécuter votre fonction N fois, une fois par ligne. Parfois, cette fonction est chère. Certaines bases de données prennent en charge les index de fonction. Mais vous ne pouvez pas indexer toutes les fonctions possibles avec toutes les entrées possibles. Ou peut vous?
Une solution courante au problème ci-dessus consiste à extraire la logique de la fonction et à la fusionner dans la requête. Maintenant, vous avez cassé l'encapsulation et la logique dupliquée.
Un autre problème que je vois est l'appel de procédures stockées dans une boucle car il n'existe aucun moyen de joindre ou d'intersecter des ensembles de résultats proc stockés.
Si vous extrayez le code du processus imbriqué, vous décentralisez à nouveau. Par conséquent, vous êtes obligé de choisir entre encapsulation et performance.
En général, je trouve que les bases de données sont mauvaises à:
Les bases de données sont bonnes à:
En effectuant des opérations coûteuses telles que l'analyse de boucles et de chaînes et en les conservant dans votre niveau d'application, vous pouvez redimensionner votre application horizontalement pour obtenir de meilleures performances. L'ajout de plusieurs serveurs d'applications derrière un équilibreur de charge est généralement beaucoup moins coûteux que la configuration de la réplication de base de données.
Vous avez cependant raison de dire que cela dissocie votre logique métier du langage de programmation de votre application, mais je ne vois pas en quoi cela constitue un avantage. Si vous avez une application Java, alors vous avez une application Java. La conversion d'un tas de code Java en procédures stockées ne change pas le fait que vous avez une application Java.
Ma préférence est de garder le code de base de données concentré sur la persistance. Comment créez-vous un nouveau widget? Vous devez insérer dans 3 tables et elles doivent être dans une transaction. Cela appartient à une procédure stockée.
La définition de ce qui peut être fait sur un widget et les règles de gestion permettant de rechercher des widgets appartiennent à votre application.
la source
J'ai travaillé dans 2 entreprises différentes qui avaient une vision différente sur le sujet.
Ma suggestion personnelle serait d'utiliser des procédures stockées lorsque le temps d'exécution est important (performance). Puisque les procédures stockées sont compilées, si vous avez une logique complexe pour interroger les données, il est préférable de la conserver sur la base de données elle-même. En outre, il n'enverra que les données finales à votre programme à la fin.
Sinon, je pense que la logique d'un programme devrait toujours être dans le logiciel lui-même. Pourquoi? Parce qu'un programme doit être testable et je ne pense pas qu'il existe un moyen simple de tester à l'unité la procédure stockée. N'oubliez pas qu'un programme non testé est un mauvais programme.
Utilisez donc la procédure stockée avec prudence, lorsque cela est nécessaire.
la source
Vous devez trouver un terrain d'entente. J'ai vu des projets effrayants dans lesquels les programmeurs utilisent la base de données comme rien de plus qu'un magasin de clé / valeur hors de prix. J'ai vu d'autres où les programmeurs échouent à utiliser des clés étrangères et des index. À l'autre extrémité du spectre, j'ai vu des projets dans lesquels la plupart, voire la totalité, de la logique métier est implémentée dans le code de base de données.
Comme vous l'avez noté, T-SQL (ou son équivalent dans d'autres SGBDR courants) n'est pas exactement le meilleur endroit pour coder une logique métier complexe.
J'essaie de créer un modèle de données raisonnablement décent, d'utiliser les fonctionnalités de la base de données pour protéger mes hypothèses sur ce modèle (c.-à-d. Les FK et les contraintes) et d'utiliser le code de la base de données avec parcimonie. Le code de la base de données est utile lorsque vous avez besoin de quelque chose (par exemple, une somme) que la base de données sait très bien faire et peut vous éviter de déplacer des zillions d'enregistrements sur le réseau lorsque vous n'en avez pas besoin.
la source
Si votre logique métier implique des opérations sur les ensembles, elle constitue probablement un emplacement approprié dans la base de données, car les systèmes de base de données sont vraiment efficaces pour effectuer des opérations sur les ensembles.
http://en.wikipedia.org/wiki/Set_operations_(SQL)
Si la logique applicative implique une sorte de calcul, elle appartient probablement en dehors de la procédure de base de données / magasin car les bases de données ne sont pas vraiment conçues pour la boucle et le calcul.
Bien que ce ne soient pas des règles strictes, c'est un bon point de départ.
la source
Il n'y a pas une seule bonne réponse à cela. Cela dépend de ce que vous utilisez la base de données. Dans une application d'entreprise, vous avez besoin de la logique de la base de données sous forme de clés étrangères, de contraintes, de déclencheurs, etc., car c'est le seul endroit où toutes les applications possibles partagent le même code. En outre, l'insertion de la logique requise dans le code signifie généralement que la base de données est incohérente et que les données sont de mauvaise qualité. Cela peut sembler trivial à un développeur d’applications qui ne se soucie que de la façon dont fonctionne l’interface graphique, mais je vous assure que les personnes essayant d’utiliser les données dans les rapports de conformité le trouvent très ennuyeux et coûteux lorsqu'elles se voient imposer des amendes d'un milliard de dollars pour avoir Suivez pas les règles correctement.
Dans un environnement non réglementaire où vous vous souciez moins de l'ensemble des enregistrements et que seulement une ou deux applications arrivent dans la base de données, vous pouvez peut-être vous en sortir en gardant tout cela dans l'application.
la source
Après quelques années, la question est toujours importante ...
Pour moi, la règle est simple: s'il s'agit d'une contrainte logique ou d'une expression omniprésente (instruction unique), placez-la dans la base de données (oui, les clés étrangères et les contraintes de vérification sont également de la logique métier!). Si c'est procédural, en contenant des boucles et des branches conditionnelles (et ne peut vraiment pas être transformé en une expression), mettez-le en code.
Éviter les bases de données de vidage de corbeille
Les tentatives visant à placer réellement toute la logique métier dans le code d’application vont probablement dégénérer la base de données (relationnelle) en un vidage de la corbeille, où la conception relationnelle est presque complètement omise, où les données peuvent avoir un état incohérent et où la normalisation est absente (souvent principalement XML, , Colonnes de corbeille CSV etc.).
Ce type de logique réservée aux applications est probablement l’une des principales raisons de l’essor de NoSQL - bien sûr, mais l’inconvénient est que l’application doit prendre en charge toute la logique elle-même, qui est intégrée à la base de données relationnelle depuis des décennies. Cependant, les bases de données NoSQL conviennent mieux à ce type de traitement de données. Par exemple, les documents de données conservent une "intégrité relationnelle" implicite en eux-mêmes. Pour les bases de données relationnelles, il s’agit tout simplement d’abus et de problèmes.
Expressions (basées sur les ensembles) au lieu de code procédural
Dans le meilleur des cas, chaque requête ou opération de données doit être codée comme une expression plutôt que comme un code de procédure. Les langages de programmation prennent en charge des expressions telles que LINQ dans le monde .NET (malheureusement, seules les requêtes pour le moment, pas de manipulation). Du côté des bases de données relationnelles, on a appris depuis longtemps à préférer les expressions d'instructions SQL aux boucles procédurales du curseur. Ainsi, la base de données peut être optimisée, effectuer l’opération en parallèle, ou ce qui peut être utile.
Utiliser les mécanismes d'intégrité des données de la base de données
Lorsqu'il s'agit de SGBDR avec une clé étrangère et des contraintes de vérification, des colonnes calculées, éventuellement des déclencheurs et des vues, c'est l'endroit idéal pour stocker la logique métier de base dans la base de données. Une normalisation appropriée aide à maintenir l'intégrité des données, afin de garantir une instance unique et distincte des données. Même si vous devez le dupliquer dans le code et la base de données, ces mécanismes de base de l'intégrité des données ne doivent pas être omis!
Procédures stockées?
Les procédures stockées sont rarement nécessaires de nos jours, car les bases de données conservent les plans d'exécution compilés pour SQL et les réutilisent lorsque la même requête revient, uniquement avec des paramètres différents. Ainsi, l'argument de précompilation pour les SP n'est plus valide. On peut stocker ou générer automatiquement des requêtes SQL dans l'application ou l'ORM, qui trouvera la plupart du temps des plans de requête précompilés. SQL est un langage d'expression, tant que vous n'utilisez pas explicitement des éléments procéduraux. Donc, dans le meilleur des cas, vous utilisez des expressions de code pouvant être traduites en SQL.
Bien que le côté application, y compris SQL généré par ORM, ne soit plus dans la base de données, contrairement aux procédures stockées, je le considère toujours comme du code de base de données. Parce qu'il nécessite toujours des connaissances en SQL et en base de données (à l'exception du CRUD le plus simple), il fonctionne de manière très différente du code de procédure généralement créé avec des langages de programmation tels que C # ou Java.
la source
Cela dépend vraiment de l'entreprise, de sa culture et de son héritage. Mis à part les considérations techniques (celles-ci ont été abordées des deux côtés), les réponses fournies indiquent qu’il s’agit de savoir d’où viennent les gens. Dans certaines organisations, les données sont primordiales et le DBA est un personnage puissant. C'est votre environnement centralisé typique, un centre de données auquel sont rattachés de nombreux terminaux. La préférence dans ce type d’environnement est claire. Le poste de travail peut changer radicalement plusieurs fois avant que quoi que ce soit ne change dans le centre de données et il y aura peu de temps entre les deux.
L’autre extrémité du spectre est l’architecture pure à 3 niveaux. Ou peut-être à plusieurs niveaux dans une entreprise orientée Web. Votre volonté entendre probablement une histoire différente ici. L’administrateur de base de données, s’il y en a un, sera juste un sidekick qui effectue certaines tâches administratives.
Un développeur d'applications des temps modernes aura plus d'affinité avec le second modèle. Si vous avez grandi avec un grand système client-serveur, vous seriez probablement dans l'autre camp.
Il y a souvent tellement de facteurs liés à l'environnement non techniques impliqués ici qu'il n'y a pas de réponse générale à cette question.
la source
Le terme logique métier est ouvert à interprétation. Lors de la construction de systèmes, nous voulons garantir l’intégrité de la base de données et de son contenu. Dans un premier temps, différentes autorisations d'accès utilisateur doivent être en place. À titre d’exemple très simple, considérons une application ATM.
Pour obtenir le solde du compte, il suffit de sélectionner une vue appropriée. Mais pour transférer des fonds, vous voudriez que la transaction soit encapsulée par une procédure stockée. La logique applicative ne doit pas être autorisée à mettre à jour directement les tables pour les montants en crédits et débits.
Dans cet exemple, la logique applicative pourrait vérifier le solde avant de demander le transfert ou simplement appeler le proc stocké pour le transfert et signaler l'échec. IMHO, la logique métier, dans cet exemple, doit vérifier de manière préventive que des fonds suffisants sont disponibles et que le compte cible existe, puis seulement appeler les fonds de transfert. Si un autre débit se produit entre les étapes initiales et l’invocation de procédure stockée, une erreur ne serait alors renvoyée.
la source