web-dev-qa-db-fra.com

quelle est la différence entre les déclencheurs, les assertions et les contrôles (dans la base de données)

Quelqu'un peut-il expliquer (ou suggérer un site ou un document) la différence exacte entre les déclencheurs, les assertions et les vérifications, et décrire également où je devrais les utiliser?

EDIT: Je veux dire dans la base de données, pas dans d’autres systèmes ou langages de programmation.

22
Am1rr3zA

Triggers - un déclencheur est une partie de SQL à exécuter avant ou après une mise à jour, une insertion ou une suppression dans une base de données. Voici un exemple de déclencheur en anglais simple: Avant de mettre à jour un enregistrement client, enregistrez une copie de l’enregistrement actuel. Ce qui ressemblerait à quelque chose comme:

CREATE TRIGGER triggerName
AFTER UPDATE
    INSERT INTO CustomerLog (blah, blah, blah)
    SELECT blah, blah, blah FROM deleted

La différence entre les assertions et les chèques est un peu plus floue, de nombreuses bases de données ne supportent même pas les assertions.

Check Constraint - Une vérification est une partie de SQL qui vérifie qu'une condition est remplie avant que des actions ne puissent être effectuées sur un enregistrement. En clair, cela ressemblerait à ceci: Tous les clients doivent avoir un solde d’au moins 100 dollars sur leur compte. Ce qui ressemblerait à quelque chose comme:

ALTER TABLE accounts 
ADD CONSTRAINT CK_minimumBalance
CHECK (balance >= 100)

Toute tentative d'insérer une valeur inférieure à 100 dans la colonne de la balance génèrerait une erreur.

Assertions - Une assertion est un fragment de code SQL garantissant le respect d'une condition ou empêchant toute action sur un objet database. Cela pourrait vouloir dire verrouiller toute la table ou même toute la base de données.

Pour rendre les choses plus confuses - un déclencheur peut être utilisé pour appliquer une contrainte de vérification et dans certaines bases de données peut remplacer une assertion (en vous permettant d'exécuter du code sans relation avec la table en cours de modification). Une erreur courante pour les débutants consiste à utiliser une contrainte de vérification lorsqu'un déclencheur est requis ou un déclencheur lorsqu'une contrainte de vérification est requise.

Un exemple: tous les nouveaux clients ouvrant un compte doivent avoir un solde de 100 $; cependant, une fois le compte ouvert, leur solde peut tomber en dessous de ce montant. Dans ce cas, vous devez utiliser un déclencheur car vous souhaitez uniquement que la condition soit évaluée lorsqu'un nouvel enregistrement est inséré.

54
jellomonkey

Dans la norme SQL, ASSERTIONS et CHECK CONSTRAINTS sont à la fois ce que la théorie relationnelle appelle "contraintes": règles auxquelles les données réellement contenues dans la base de données doivent se conformer.

La différence entre les deux est que CHECK CONSTRAINTS est, dans un sens, beaucoup plus "simple": ce sont des règles qui ne concernent qu'une seule ligne, tandis que ASSERTIONs peut impliquer un nombre quelconque d'autres tables, ou un nombre quelconque d'autres lignes dans la même. table. Cela rend évidemment (beaucoup!) Plus complexe pour les constructeurs de SGBD de le prendre en charge, et c’est la raison pour laquelle ils ne le font pas: ils ne savent tout simplement pas comment le faire.

Les TRIGGER sont des morceaux de code exécutable dont on peut déclarer au SGBD que ceux-ci doivent être exécutés chaque fois qu'un certain type d'opération de mise à jour (insertion/suppression/mise à jour) est effectué sur une certaine table. Les déclencheurs pouvant générer des exceptions, ils constituent un MOYEN pour implémenter la même chose qu'une ASSERTION. Cependant, avec les déclencheurs, c'est toujours le programmeur qui doit faire tout le codage et ne pas faire d'erreur.

MODIFIER

Un jour où les commentaires re. ASSERTION/VÉRIFICATION cnstr. sont corrects. La différence est beaucoup plus subtile (et déroutant). La norme autorise en effet les sous-requêtes dans les contraintes CHECK. (Cependant, la plupart des produits ne le prennent pas en charge, mon "lien avec une seule ligne" est vrai pour la plupart des produits SQL, mais pas pour la norme.) Y a-t-il encore une différence? Oui il y a toujours. Plus d'un même.

Premier cas: TABLE MEN (ID: INTEGER) et TABLE WOMEN (ID: INTEGER). Imaginez maintenant une règle selon laquelle "aucune valeur d’ID ne peut apparaître à la fois dans la table MEN et dans la table WOMEN". C'est une seule règle. L’intention d’ASSERTION est précisément que le concepteur de base de données énonce cette règle unique [et qu’il en soit tenu compte], et que le SGBD sache comment traiter cela [efficacement, bien sûr] et comment appliquer cette règle, quel que soit le cas particulier. mise à jour se fait à la base de données. Dans l'exemple, le SGBD sait qu'il doit vérifier cette règle lors de l'insertion INSERT INTO MEN, et lors de l'insertion INSERT INTO WOMEN, mais pas lors de la suppression de DELETE FROM MEN/WOMEN ou de la commande INSERT INTO <anyothertable>.

Mais les SGBD ne sont pas assez intelligents pour faire tout cela. Alors que faut-il faire? Le concepteur de base de données doit ajouter deux contraintes de contrôle de vérification à sa base de données, une à la table MEN (en vérifiant les ID MEN nouvellement insérés par rapport à la table WOMEN) et une à la table WOMAN (en effectuant l'inverse). Il y a votre première différence: une règle, une ASSERTION,DEUXCHECK contraintes. Les contraintes de CHECK représentent un niveau d'abstraction inférieur à celui de ASSERTION, car elles obligent le concepteur à réfléchir davantage sur (a) tous les types de mise à jour qui pourraient potentiellement causer la violation de son ASSERTION et (b) quelle vérification particulière devrait être effectuée. pour tous les "types de mise à jour" spécifiques qu’il a trouvées dans (a). (Bien que je n'aime pas vraiment faire des déclarations "absolues" sur ce qui est toujours "QUOI" et ce qui est "COMMENT", je résumerais que les contraintes de CHECK nécessitent plus de "COMMENT" (réflexion) (procédurale) de la part du concepteur de base de données, alors que ASSERTION permettre au concepteur de base de données de se concentrer exclusivement sur le "QUOI" (déclaratif).)

Deuxième cas (bien que je ne sois pas tout à fait sûr de cela - prenez donc avec un grain de sel): juste votre règle de RI moyenne. Bien entendu, vous avez l'habitude de spécifier cela à l'aide de la clause REFERENCES. Mais imaginons qu'une clause REFERENCES n'était pas disponible. Une règle du type "Chaque COMMANDE doit être passée par un CLIENT connu" n’est en réalité qu’une règle, donc: une seule ASSERTION. Cependant, nous savons tous qu’une telle règle peut toujours être enfreinte de deux manières: insérer un ORDER (dans cet exemple) et supprimer un CLIENT. Maintenant, conformément à l'exemple précédent de MAN/WOMEN, si nous voulions implémenter cette règle unique/ASSERTION à l'aide de contraintes CHECK, nous devrions alors écrire une contrainte CHECK qui vérifie l'existence du CLIENT lors de son insertion dans ORDER, mais quelle contrainte CHECK pourrait nous écrivons que fait tout ce qui est nécessaire lors de suppression de CLIENT? Ils ne sont tout simplement pas conçus à cette fin, autant que je sache. Deuxième différence: les contraintes de CHECK sont liées à des INSERT exclusivement. ASSERTIONS peut définir des règles qui seront également vérifiées lors de SUPPRESSION.Troisième cas: imaginez un tableau COMPOS (composantID: ... pourcentage: INTEGER) et une règle selon laquelle "la somme de tous les pourcentages doit toujours être égale à 100". C'est une règle unique, et une ASSERTION est capable de le spécifier. Mais essayez d’imaginer comment appliquer une telle règle avec des contraintes CHECK ... Si vous avez une table valide avec, par exemple, trois lignes non nulles totalisant une centaine, comment appliqueriez-vous les modifications qui surviendraient à cette table votre contrainte de CHECK? Vous ne pouvez pas supprimer ou mettre à jour (diminuer) une ligne sans avoir à ajouter d'autres lignes à remplacer ou mettre à jour les lignes restantes, qui totalisent le même pourcentage. De même pour insérer ou mettre à jour (augmenter). Vous auriez besoin au minimum d'une vérification de contrainte différée, puis qu'allez-vous vérifier? Il y a votre troisième différence: les contraintes CHECK ciblent des lignes individuelles, tandis que ASSERTION peut également définir/exprimer des règles qui "s'étendent" sur plusieurs lignes (c'est-à-dire des règles sur les agrégations de lignes).

Third case : Imagine a table COMPOS (componentID:... percentage:INTEGER), and a rule to the effect that "the sum of all percentages must at all times be equal to 100". That's a single rule, and an ASSERTION is capable of specifying that. But try and imagine how you would go about enforcing such a rule with CHECK constraints ... If you have a valid table with, say, three nonzero rows adding up to a hundred, how would you apply any change to this table that could survive your CHECK constraint ? You can't delete or update(decrease) any row without having to add other replacing rows, or update the remaining rows, that sum up to the same percentage. Likewise for insert or update (increase). You'd need deferred constraint checking at the very least, and then what are you going to CHECK ? There's your third difference : CHECK constraints are targeted to individual rows, while ASSERTIONs can also define/express rules that "span" several rows (i.e. rules about aggregations of rows).

11
Erwin Smout

Les assertions ne modifient pas les données, elles ne vérifient que certaines conditions.

Les déclencheurs sont plus puissants car ils peuvent vérifier les conditions et modifier les données

-------------------------------------------------- ------------------------------

Les assertions ne sont pas liées à des tables spécifiques de la base de données ni à des événements spécifiques.

Les déclencheurs sont liés à des tables spécifiques et à des événements spécifiques

5
Mohamed Adel

Une contrainte de base de données implique une condition qui doit être remplie lorsque la base de données est mise à jour. En SQL, si une condition de contrainte est évaluée à false, la mise à jour échoue, les données restent inchangées et le SGBD génère une erreur.

CHECK et ASSERTION sont des contraintes de base de données définies par les normes SQL. Une distinction importante est qu'une CHECK est appliquée à une table de base spécifique, alors qu'une ASSERTION est appliquée à la base de données entière. Considérons une contrainte qui limite les lignes combinées des tables T1 et T2 à un total de 10 lignes, par exemple. 

CHECK (10 >= (
              SELECT COUNT(*)
                FROM (
                      SELECT *
                        FROM T1
                      UNION
                      SELECT * 
                        FROM T2
                     ) AS Tn
             ))

Supposons que les tables sont vides. Si cela était appliqué uniquement à ASSERTION et qu'un utilisateur tentait d'insérer 11 lignes dans T1, la mise à jour échouerait. La même chose s'appliquerait si la contrainte était appliquée en tant que contrainte CHECK à T1 uniquement. Toutefois, si la contrainte était appliquée en tant que contrainte CHECK à T2, seule la contrainte réussirait, car une instruction ciblant T1 ne permet pas de tester les contraintes appliquées à T1.

Une ASSERTION et une CHECK peuvent être différées (si déclaré DEFERRABLE), permettant ainsi aux données de violer temporairement la condition de contrainte, mais uniquement dans le cadre d'une transaction.

Les contraintes ASSERTION et CHECK impliquant des sous-requêtes sont des fonctionnalités extérieures à SQL Standard principal et aucun des principaux produits SQL ne prend en charge ces fonctionnalités. MS Access (pas exactement un produit industriel) prend en charge les contraintes CHECK impliquant des sous-requêtes mais pas les contraintes différables. En outre, le test des contraintes est toujours effectué ligne par ligne, la fonctionnalité étant par conséquent très limitée.

Comme avec les contraintes CHECK, un déclencheur est appliqué à une table spécifique. Par conséquent, un déclencheur peut être utilisé pour implémenter la même logique qu'une contrainte CHECK mais pas une ASSERTION. Un déclencheur est un code de procédure et, contrairement aux contraintes, l'utilisateur doit assumer davantage de responsabilités pour des problèmes tels que les performances et la gestion des erreurs. La plupart des produits SQL commerciaux prennent en charge les déclencheurs (MS Access susmentionné ne le fait pas).

1
onedaywhen

L'expression doit être vraie pour que le déclencheur se déclenche, mais check sera évalué chaque fois que l'expression est fausse.

0
Feri