9
votes

Plusieurs déclencheurs vs un seul déclencheur

scénario:

Chaque fois que les données de temps sont insérées / mises à jour / supprimées dans / dans / dans la table, jusqu'à 3 choses doivent arriver:

  1. Les données doivent être connectées à une table séparée
  2. L'intégrité référenciale doit être appliquée sur des données implicites connexes (je parle de données pouvant être liées à une relation de clé étrangère, mais n'est pas la suivante: par exemple, lors de la mise à jour Table1.name devrait Également mettre à jour table2.name à la même valeur)
  3. La logique commerciale arbitraire doit exécuter

    L'architecture et le schéma de la base de données ne doivent pas être modifiés et les exigences doivent être accomplies en utilisant des déclencheurs.

    question

    Quelle option est la meilleure?:

    1. Un seul déclencheur par opération (insertion / mise à jour / Supprimer) qui gère de multiples préoccupations (journaux, applique une intégrité référenciale implicite et exécute la logique commerciale arbitraire). Ce déclencheur pourrait être nommé d_tablename ("D" pour Suppr).
    2. Les déclencheurs multiples par opération séparés par la préoccupation. Ils pourraient être nommés:

      • d_tablename_logging - pour la journalisation lorsque quelque chose est supprimé de
      • d_tablename_ri
      • d_tablename_bl

        Je préfère l'option 2 car une seule unité de code a une seule préoccupation. Je ne suis pas un DBA et j'en connais assez sur SQL Server pour me rendre dangereux.

        Y a-t-il des raisons impérieuses de gérer toutes les préoccupations dans un seul déclencheur?


5 commentaires

Est-ce une base de données de volume de transaction à haute transaction?


La base de données a 100 utilisateurs simultanés.


Je serais très préoccupé par les goulots d'étranglement de la performance causés par des déclencheurs en cascade, en particulier si même des dizaines d'utilisateurs peuvent être modifiant simultanément la base de données.


"Une fonction devrait faire une chose seulement"


@Neilmcguigan - ne s'applique pas nécessairement à SQL. Je ne voudrais pas avoir à numériser la même table plusieurs fois dans plusieurs déclencheurs différents ou à mettre à jour différentes colonnes de la même ligne plusieurs fois pour éviter de violer le SRP.


4 Réponses :


4
votes

WOW, vous êtes dans une situation sans gagnant. Qui a déjà demandé que toutes ces choses soient faites par des déclencheurs devraient être tirées puis tirées. Appliquer RI via des déclencheurs?

Vous avez dit que l'architecture et le schéma de la base de données ne doivent pas être modifiés. Cependant, en créant des déclencheurs, vous êtes à tout le moins de changer le schéma de la base de données et, cela pourrait être argumenté, l'architecture.

J'irais probablement avec l'option n ° 1 et créerais des Procs et UDF stockés supplémentaires qui prennent soin de la journalisation, BL et RI afin que le code ne soit pas dupliqué AMOUNG Les déclencheurs individuels (les déclencheurs appelleraient ces processus et / ou UDFS stockés). . Je n'aime vraiment pas nommer les déclencheurs qu'ils ont proposé dans l'option 2.

BTW, veuillez dire à quelqu'un à votre organisation que c'est fou. RI ne doit pas être appliqué via des déclencheurs et une logique commerciale n'appartient pas à la base de données.


10 commentaires

Le problème avec les procédures stockées et les UDFS ici est qu'ils n'ont pas accès à inséré et supprimé sauf si vous allez les copier dans une TVP.


@Martinsmith - ou mettez-les dans une table Temp d'abord. Difficile de dire quelle est la bonne approche donnée quelles sont les petites exigences ont été présentées.


@RandyMinder - Fonctions ne peut pas accéder à #temp Tables.


@Martinsmith - Oui, c'est vrai. Les UDF peuvent ne pas fonctionner dans ce cas et ne sont probablement pas nécessaires si les PROC stockés feront le travail.


La logique d'entreprise appartient à la recherche de l'entreprise.


@ypercube - faux. L'entreprise ne comprend pas quelles sont les forces et les faiblesses d'une base de données.


Je ne comprends vraiment pas votre dernier paragraphe. RI modèles logique commercial, aussi. Pourquoi cela appartient-il dans la base de données?


@ypercube - Savez-vous quelle clé étrangère est?


@RandyMinder Quelle est votre convention de dénomination préférée?


@Dan - dépend de l'option avec laquelle vous allez. Si c'est l'option 1, notre standard est Tablename_ . Donc, cela pourrait être quelque chose comme myTable_insert, myTable_update ou myTable_insertupdate. De cette façon, il est clair lorsque le tiger incendie, en regardant le nom. BTW, nous éliminons l'utilisation de déclencheurs de notre société. À l'exception des utilisations isolées, ils causent beaucoup plus de problèmes qu'ils ne résolvent. Nos bases de données sont strictement pour la persistance des données. Tous les BL, la journalisation, etc. sont contenus dans le code de service C # de niveau moyen.



4
votes

Faire tout cela dans un déclencheur peut être plus efficace en ce que vous pouvez éventuellement vous retrouver avec moins d'opérations contre le (ONU INDED) inséré et supprimé Tables.

De plus, lorsque vous avez de multiples déclencheurs, il est possible de définir le premier et le dernier qui déclenche, mais tout autre incendie dans l'ordre arbitraire afin que vous ne puissiez pas contrôler la séquence des événements déterminisciquement si vous avez plus de 3 déclencheurs pour un particulier action.

Si aucune de ces considérations ne s'applique, il s'agit simplement d'une question de préférence.

Bien sûr, il va sans dire que la spécification de le faire avec des déclencheurs est nul.


0 commentaires

2
votes

Je suis d'accord avec @RandyMinder. Cependant, j'irais plus loin. Les déclencheurs ne sont pas la bonne façon d'aborder cette situation. La logique que vous décrivez est trop compliquée pour le mécanisme de déclenchement.

Vous devez envelopper des inserts / mises à jour / supprime dans les procédures stockées. Ces procédures stockées peuvent gérer la logique commerciale et la journalisation et ainsi de suite. En outre, ils rendent évidents ce qui se passe. Une chaîne de procédures stockées appelant des procédures stockées est explicite. Une chaîne de déclencheurs appelant des déclencheurs est déterminée par insertion / mise à jour / supprimer des instructions qui ne font pas appel à la gâchette explicite.

Le problème avec les déclencheurs est qu'ils introduisent des dépendances et un verrouillage parmi les tables disparates, et il peut s'agir d'un cauchemar pour démêler les dépendances. De même, il peut s'agir d'un cauchemar pour déterminer les goulots d'étranglement de la performance lorsque le problème peut être situé dans une gâchette appelant une gâchette appelant une procédure stockée appelant un déclencheur.


1 commentaires

Je suis totalement d'accord avec vous que les déclencheurs ne sont pas comment cela devrait être manipulé. La raison pour laquelle une exigence a trait à soutenir une solution héritée.



0
votes

Si vous utilisez Microsoft SQL Server et que vous pouvez modifier le code exécutant les instructions DML, vous pouvez utiliser le clause de sortie pour vider les valeurs mises à jour, insérées, supprimées dans des tables temporaires ou des variables de mémoire au lieu de déclencheurs. Cela gardera une pénalité de performance au minimum.


0 commentaires