Ai-je vraiment besoin de déclencheurs pour une base de données relationnelle, par exemple, PostgreSQL?

10

Je sais que les déclencheurs peuvent être utilisés pour valider les données stockées afin de garder la base de données cohérente. Mais pourquoi ne pas valider les données côté application avant de les stocker dans la base de données?

Par exemple, nous stockons des clients et nous voulons effectuer une validation qui ne peut pas être facilement effectuée au niveau DDL. https://severalnines.com/blog/postgresql-triggers-and-stored-function-basics

Un autre exemple est l'audit.

Mise à jour

Comment les déclencheurs et les transactions de base de données fonctionnent ensemble. Par exemple, si je souhaite effectuer la validation des données insérées. Cela se fait à l'intérieur d'une transaction. Que se passe-t-il plus tôt: la transaction est validée ou le déclencheur est exécuté?

Yan Khonski
la source
However, why not perform validation of data on the application side before storing them into the database?eh bien, ces deux-là ne s'excluent pas mutuellement. Il est probable que vous validerez différentes choses des deux côtés. Alors que les validations côté application sont centrées sur l'entreprise, les validations sur la base de données sont plus centrées sur les données. Pensez dans une base de données alimentée par plusieurs applications différentes.
Laiv
Aurez-vous besoin d'insérer des données provenant d'une source extérieure qui effectue simplement un vidage insensé de données dans votre système? Si tel est le cas, il se peut que vous ayez besoin d'insérer les données dans un format non valide pour une correction ultérieure. Dans ce cas, les déclencheurs causeront des problèmes sans fin. Gardez cela à l'esprit. Parfois, vous ne voulez pas qu'un déclencheur soit exécuté.
Greg Burghardt
Votre mise à jour devrait être une question en soi, peut-être sur SO, mais votre question a déjà une réponse sur Database Administrators.SE . En bref, même un déclencheur "après mise à jour" est exécuté avant que la transaction ne soit validée, et si une exception est levée à l'intérieur du déclencheur, elle entraînera une restauration.
Doc Brown
@GregBurghardt La plupart des bases de données ont des instructions qui peuvent être utilisées pour désactiver les déclencheurs pour ce type d'activités.
Blrfl
1
@Blrfl: Oui, mais vous devez savoir que ces déclencheurs peuvent être désactivés temporairement pour tous les utilisateurs connectés, lorsque vous ne souhaitez désactiver que conditionnellement ces vérifications pour la session en cours.
Greg Burghardt

Réponses:

12

Cela dépend du type de système d'application que vous construisez:

  • si vous créez un système centré sur l'application qui contient une seule application principale, avec une base de données dédiée spécifiquement pour cette application, et idéalement une équipe chargée de faire évoluer l'application et la base de données côte à côte, vous pouvez conserver toute la logique de validation et également l'audit logique à l'intérieur de l'application.

    Le principal avantage de ceci est que vous n'avez pas à répartir la logique métier entre l'application et la base de données, donc la maintenance et l'évolution du système deviennent souvent plus faciles. En prime, vous ne liez pas trop l'application à un type spécifique de SGBD ou de fournisseur de SGBD. Cette approche est évidemment nécessaire si votre application veut pouvoir utiliser un système DB léger qui ne fournit pas de déclencheurs.

  • Si, cependant, vous créez un système où de nombreuses applications différentes partagent une base de données commune, et qu'il ne peut pas imaginer à l'avance quelles applications y écriront à l'avenir, ou quelles équipes développeront des applications pour remplir des données dans la base de données à l'avenir, alors il il vaut mieux que votre base de données soit chargée de garantir autant de cohérence des données que possible. Et c'est là que les déclencheurs deviennent vraiment utiles. Dans les grands systèmes, les contraintes référentielles ne sont souvent pas suffisantes pour cela, mais un déclencheur qui appelle une procédure stockée peut implémenter presque tout type de validation dont vous avez besoin.

Une autre raison de l'utilisation des déclencheurs peut être la performance: dans les modèles de données complexes, il n'est pas rare de rencontrer des règles de cohérence complexes qui nécessitent d'utiliser beaucoup de données supplémentaires qui ne font pas partie de l'ensemble de travail actuel disponible dans l'application cliente. Le transfert de toutes ces données sur le réseau en premier pour permettre la validation côté client peut avoir un impact notable sur les performances.

Voir également cet ancien article SE: Application Logic Vs DB Triggers pour le nettoyage de la base de données

Décidez donc vous-même du type de système que vous construisez, puis vous pourrez décider si les déclencheurs sont le bon outil pour votre cas ou non.

Doc Brown
la source
3

Je pense que la question porte sur la responsabilité de la qualité des données.

La réponse dépend de la façon dont vous voyez le système.

Si vous voyez la base de données comme un service indépendant, distinct et autonome distinct de l'application, alors la base de données est chargée d'assurer la cohérence et la qualité des données qu'elle contient. Essentiellement parce que cette base de données pourrait être utilisée par une autre application, elle ne peut donc pas compter sur cette deuxième application ayant les mêmes comportements de cohérence et de qualité. Dans ces circonstances, la base de données doit être conçue pour exposer une API et un comportement autonome. Dans cette vue, il existe au moins deux applications, l'une d'entre elles est la base de données et l'autre est l'application qui l'utilise.

Inversement, la base de données pourrait être considérée comme une forme compliquée de fichier qui est sous le contrôle direct et total de l'application. En ce sens, la base de données devient un pur outil de sérialisation et de navigation dans les documents. Il peut fournir certains comportements avancés pour prendre en charge les requêtes et la maintenance des documents (comme le font les outils JSON ou XML), mais il n'est pas nécessaire de le faire (comme la plupart des flux de fichiers). Dans ce cas, il incombe uniquement aux programmes de conserver le format et le contenu corrects dans le fichier. Dans cette vue, il y a une application.

Dans les deux vues, la question suivante est de savoir comment prendre en charge l'utilisation de la base de données en tant que fichier de fantaisie ou service distinct. Vous pouvez y parvenir en:

  • en utilisant les outils que la plateforme de base de données fournit sous forme de tables / vues / procédures stockées / déclencheurs / etc ...
  • encapsuler la base de données elle-même dans un service que tous les clients doivent utiliser pour accéder à la base de données
  • encapsuler la base de données dans une bibliothèque qui doit être utilisée par tous les clients pour accéder aux données.

Chacun a ses avantages et ses inconvénients et dépendra des contraintes architecturales de l'environnement dans lequel le système fonctionne.

Quelle que soit la vue que vous adoptez, il est toujours avantageux de valider les données aux limites.

  • Valider les champs d'une interface utilisateur saisis par un utilisateur
  • Valider la demande de réseau / API avant qu'elle ne quitte le client
  • Validez la requête réseau / API sur le serveur avant de faire quoi que ce soit
  • Valider les données transmises dans les règles métier
  • Valider les données avant de persister
  • Valider les données après avoir été récupérées de la persistance
  • ainsi de suite et ainsi de suite

La quantité de validation garantie à chaque frontière dépend du risque de ne pas la valider.

  • multiplier deux nombres ensemble?
    • vous obtenez le mauvais numéro est-ce un problème?
  • invoquer une procédure sur un emplacement mémoire donné?
    • Qu'y a-t-il dans cet emplacement mémoire?
    • Que se passe-t-il si l'objet n'existe pas ou est en mauvais état?
  • à l'aide d'une expression régulière sur une chaîne contenant des kanji?
    • Le module regex peut-il gérer unicode?
    • Le regex peut-il gérer unicode?
Kain0_0
la source
La centralisation de la logique de validation est bonne, mais les déclencheurs imho ne sont pas un bon moyen de l'implémenter. J'avais l'habitude de travailler sur un système où plusieurs applications partageaient toutes une base de données, avec toute la logique de validation et les effets secondaires implémentés dans la base de données via des déclencheurs et des procédures stockées. Je suis reparti avec l'impression qu'il valait mieux avoir un microservice devant la base de données et y implémenter toute la logique. La logique non triviale dans une base de données SQL est un anti-modèle.
Joeri Sebrechts
1
@JoeriSebrechts D'accord, je vais mordre: pourquoi la logique non triviale dans une base de données est-elle un contre-motif, et qu'est-ce qui en fait plus un contre-motif que de le mettre dans un programme géré séparément?
Blrfl
@Blrfl Deux raisons, l'API pour accéder à la logique dans la base de données est inférieure à une API de service Web (plus difficile à mettre à jour, plus difficile à utiliser, pas facilement mise en cache, ...), et les bases de données rendent plus difficile la structure propre et la maintenance de la base de code hébergée à l'intérieur d'eux. D'après mon expérience, il est plus facile d'héberger la logique dans un service Web devant la base de données qu'à l'intérieur de cette base de données.
Joeri Sebrechts
@JoeriSebrechts Je suis d'accord que la plupart des plateformes de bases de données fournissent des outils déplorables pour implémenter une API crédible, utile et évolutive. À bien des égards, c'est certainement une invitation à ressentir beaucoup de douleur. Mon point était qu'il s'agissait de perspective, de réaliser que la base de données est un fichier de fantaisie, ou qu'il s'agit vraiment d'un service distinct, ce qui conduit à la question suivante qui est de savoir comment envelopper cela pour prendre en charge ce style d'utilisation. Je vais élaborer ma réponse pour être clair à ce sujet.
Kain0_0
2

Non, vous ne devez jamais utiliser de déclencheurs pour effectuer la validation.

La base de données n'est responsable que de sa propre intégrité. Tout utilisateur confronté à la validation doit être effectué par votre application.

Les bases de données effectuent trois niveaux de validation de l'intégrité. Le premier est la validation au niveau du champ. Un champ peut être requis, s'il n'y a pas de valeur (null) c'est une erreur. Il peut également s'agir d'une contrainte de vérification; un domaine a un nombre énuméré de valeurs.

Deuxièmement, il existe des relations entre les tables. Dans une table, vous stockez une ou plusieurs clés étrangères, en reliant cette table à d'autres tables et en exigeant que les valeurs soient des clés valides pour "l'autre table". Pensez à une base de données d'adresses, où nous prenons en charge les adresses de différents pays. Une clé de pays dans une adresse doit pointer vers un pays connu. La validité des données (par exemple, un code postal) n'est pas une préoccupation de ce contrôle d'intégrité.

Troisièmement, les déclencheurs sont les plus compliqués. En règle générale, celles-ci devraient répondre (jeu de mots non intentionnel) aux règles d'intégrité conditionnelles. Pour revenir à l'exemple d'adresse: si un pays n'a pas de code postal, ce serait un problème si un pays de cette liste avait un code postal. La vérification serait donc la suivante: si ce pays n'a pas de codes postaux, le champ du code postal doit être nul.

La validation est la préoccupation de l'application. Le fait qu'un code postal allemand ne soit composé que de chiffres est un contrôle que l'application doit effectuer, pas la base de données. La ligne est mince, vous devrez donc peut-être réfléchir / discuter dans certains cas si quelque chose doit être dans un déclencheur (protéger l'intégrité de votre base de données) ou dans l'application (utilisateur face à la validation).

Menno Hölscher
la source
Je voulais juste ajouter que si l'OP doit ajouter une règle de validation complexe qui doit être dans la base de données, il peut toujours utiliser des procédures stockées comme alternative plus sûre.
Borjab
@Borjab: Validation comme pour maintenir la base de données correcte, peut-être. Mais l'utilisateur face à la validation? Non.
Menno Hölscher
1
Votre première déclaration dit "n'utilisez jamais de déclencheurs pour faire la validation" , mais ci-dessous vous écrivez, "oui, vous pouvez utiliser des déclencheurs pour certains types de validation, et il n'est pas intrinsèquement clair où tracer la ligne". Cela se lit tout à fait contradictoire. Je recommanderais de supprimer votre première phrase, ce qui améliorerait considérablement votre réponse. Oh, et votre dernière phrase ne répond pas à la question de mise à jour des PO, car "avant / après" n'a rien à voir avec la transaction. Je recommanderais également de le supprimer. (voir mon commentaire sous la question des PO).
Doc Brown
@DocBrown La distinction est entre la protection de la base de données contre la corruption et la validation face à l'utilisateur. Donc, dans "toute autre validation", je me réfère à la validation face à l'utilisateur. Comment pourrais-je clarifier cette distinction? Pour commencer, j'ai supprimé le "plus loin".
Menno Hölscher
2
Il est parfaitement possible d'effectuer une validation dans la base de données. Tout comme il est bon de le faire dans l'application. Les deux ont leurs avantages. Faire votre validation dans l'application signifie que vous devez être très prudent chaque fois que vous exécutez SQL sans votre ORM, ce qui est nécessaire pour à peu près toutes les applications complexes.
Qwertie
1

L'audit est un exemple classique de l'utilisation efficace des déclencheurs. J'ai trouvé des erreurs commises par le testeur (déplacement d'un client d'un niveau de service à un autre) grâce à une table d'audit implémentée par des triggers. Je recommande fortement d'utiliser des déclencheurs pour l'audit.

La validation pourrait être effectuée au niveau du front-end, mais j'ai vu des erreurs étranges dans la base de données que j'ai gérée (des personnes nées en 3000, etc.), et puisque certaines d'entre elles se sont faites moi-même, je recommande fortement d'avoir une couche supplémentaire de validation dans la base de données, juste au cas où. Bien sûr, ces types d'erreurs pourraient être évités avec des contraintes de vérification, et souvent elles sont plus efficaces (dans MS SQL, elles sont la méthode préférée; vérifiez toujours la documentation).

Hila DG
la source
1

Parce que la question est de savoir si nous avons vraiment besoin de déclencheurs pour les bases de données relationnelles, voici d'autres cas d'utilisation où utiliser des déclencheurs:

  1. Pour l'audit comme décrit dans les autres réponses.
  2. Audit au sens large: si une entrée de base de données est modifiée, un déclencheur peut enregistrer l'événement pour un post-traitement asychrone, par exemple des exportations nocturnes vers une autre application.
  3. Déclencheurs pour les vues: les déclencheurs peuvent être définis instead of. Avec cela, on peut insérer, mettre à jour et supprimer des entrées d'une vue. Les déclencheurs peuvent répartir ces actions sur plusieurs tables. C'est un moyen de rendre une vue restreinte disponible sans exposer les détails des tables sous-jacentes.
  4. Pour enregistrer explicitement les retournements de base de données: supposez une relation N: M entre les tables A et B et une table intermédiaire R. Vous pouvez définir des contraintes de clé étrangère de R vers A ainsi que B spécifiant que l'entrée dans R doit être supprimée si son l'entrée correspondante en B est supprimée. Cependant, la logique métier requiert parfois que les entrées dans A doivent avoir au moins une relation avec une entrée dans B. Dans ce cas, un déclencheur sur la suppression de R peut aider à appliquer cette logique: si pour une entrée dans A la dernière entrée dans R est supprimé, le déclencheur peut supprimer A. Dans la vue centrée sur l'application, au moins deux tours sont nécessaires. Ceci est un exemple de validation. D'autres exemples sont envisageables: à côté des cas d'utilisation (1), (2),
  5. Confiance: parfois, les administrateurs de base de données modifient les entrées sur la ligne de commande sans utiliser votre application. Les administrateurs travaillent soigneusement et savent ce qu'ils font. Cependant, ils peuvent parfois se tromper. Si la cohérence est critique, un déclencheur est leur ceinture de sécurité.

En tant qu'inconvénient, la logique métier est répartie entre les couches, ce qui constitue un inconvénient majeur pour la maintenance. Comme l'a écrit un autre auteur, il s'agit d'une mince frontière entre l'application et la base de données et le choix n'est pas toujours clair. Mon opinion personnelle est que les déclencheurs imposent un fardeau aux développeurs. Ils peuvent gagner du temps dans le développement. Ils améliorent définitivement l'expérience utilisateur car ils améliorent les performances sur des connexions réseau lentes.

Claude
la source