Contraintes et Déclencheurs¶
- Les contraintes peuvent être définies dans les instructions
create table - Ou ajoutées aux tables existantes avec les instructions
alter table - Différents types de contraintes
nullounot null- Clé primaire
- Unique
- Clé étrangère
- Check
- Domaine
- Assertion
Contraintes null ou not null¶
- Une colonne peut permettre des valeurs
null - Ou les interdire avec
not null - Par défaut : permettre des valeurs
null
Contraintes de clé primaire¶
- Une colonne ou un groupe de colonnes peut être désigné comme
primary key( clé primaire) - Les colonnes de clé primaire ne peuvent pas être
null - implicite
not nullpour chaque colonne de clé primaire - Nous pouvons utiliser une contrainte de colonne si la clé primaire n’a qu’une
seule colonne
sid integer primary key
- Si la clé primaire a plus d’une colonne, nous devons utiliser une contrainte
de table
- spécifiée après toutes les colonnes dans l’instruction
create table primary key(eid, sid)
- spécifiée après toutes les colonnes dans l’instruction
Contraintes uniques¶
- Comme les clés primaires, mais pour les clés candidates (secondaires)
- Définies de la même manière, mais avec
uniqueau lieu deprimary key - Exemple :
- ajout d’une contrainte
uniqueà la colonnecodede la tablecourse
- ajout d’une contrainte
set search_path to university;
-- alter table course drop constraint course_code_key;
alter table course
add unique (code);
insert into course(name, code, credits)
values ('Data Structures', 'DS', 3);
-- delete from course where code = 'DS';
Contraintes de clé étrangère¶
- Références à d’autres tables
- Se réfère généralement aux clés primaires dans d’autres tables
- Généralement créées pour représenter des relations lors de la traduction d’un diagramme ER en schéma relationnel
- Une colonne ou un groupe de colonnes peut être des références à une colonne ou un groupe de colonnes dans une autre table
- Nous pouvons utiliser une contrainte de colonne si la clé étrangère n’a qu’une
seule colonne
sid integer references student(sid)
- Si la clé étrangère a plus d’une colonne, nous devons utiliser une contrainte
de table
- spécifiée après toutes les colonnes dans l’instruction
create table foreign key(eid, sid) references enrollment(eid, sid)
- spécifiée après toutes les colonnes dans l’instruction
Politique des contraintes de clé étrangère¶
- Lorsque nous insérons une nouvelle ligne dans une table avec une clé
étrangère, la valeur que nous spécifions pour la ou les colonnes de clé
étrangère doit exister dans l’autre table à laquelle nous nous référons
- cela est souvent appelé une contrainte d’intégrité référentielle
- cela correspond généralement à une relation many-exactly-one ( plusieurs-exactement-un)
- exception : si nous permettons des valeurs
nullpour la ou les colonnes de clé étrangère, alors les valeursnulln’ont pas besoin d’exister dans l’autre table - et les valeurs
nulln’existeront généralement pas car la ou les colonnes auxquelles la clé étrangère se réfère seront généralement des colonnes de clé primaire - cela correspond généralement à une relation many-at-most-one ( plusieurs-au-plus-un)
- Mais que se passe-t-il lorsque nous supprimons ou mettons à jour une ligne
dans la table à laquelle la clé étrangère se réfère ?
- Si la valeur à laquelle la ou les colonnes de clé étrangère se réfèrent n’existe plus, que faisons-nous ?
- Dans les standards SQL, les actions valides sont
RESTRICT,CASCADE,SET NULL,NO ACTIONetSET DEFAULT- Toutes les actions valides ne sont pas implémentées dans tous les SGBDR
- La politique par défaut des clés étrangères est
RESTRICT- si l’exécution de la mise à jour ou de la suppression laisserait des lignes “orphelines” (lignes qui se réfèrent à des valeurs inexistantes), alors bloquer la mise à jour ou la suppression et renvoyer un message d’erreur
NO ACTIONest un synonyme deRESTRICT
- Si la politique
CASCADEest définie- alors les changements sont propagés aux lignes dépendant de la ligne originale
- si la ligne est supprimée, alors les lignes dépendant d’elle seront également supprimées (très dangereux)
- si la ligne est mise à jour, alors les lignes dépendant d’elle seront également mises à jour
- Si la politique est définie sur
SET NULLouSET DEFAULT, elle remplacera les valeurs de la ou des colonnes de clé étrangère par la valeurnullou par la valeur par défaut, si possible
Contraintes check¶
- Vérifie une expression avant d’effectuer une insertion ou une mise à jour
- si l’expression est fausse, alors l’insertion ou la mise à jour échouera
- sinon, elle réussira
- attention : si l’expression évalue à
null, alors l’insertion ou la mise à jour réussira
- Si les contraintes
checkse réfèrent à une seule colonne, elles peuvent être spécifiées comme une contrainte de colonnescore integer check(score >= 0 and score <= 100)
- Si les contraintes
checkse réfèrent à 2 colonnes ou plus, elles doivent être spécifiées comme une contrainte de tablecheck(end_date >= start_date)- notez que si l’une des dates est
null, l’expression seranullet la vérification passera
Contraintes de domaine¶
- Un domaine est utilisé pour restreindre les valeurs possibles pour un type de données
- Un domaine
- peut avoir une valeur par défaut
- peut être défini avec une contrainte
nullounot null - peut avoir une ou plusieurs contraintes
check
- Un domaine peut être utilisé pour éviter de répéter trop de contraintes, en
particulier les contraintes
checkcreate domain score as integer check(score >= 0 and score <= 100)
Assertions¶
- Contraintes générales qui peuvent s’appliquer à plus d’une ligne d’une table ou à des colonnes de plus d’une table
- Comme des contraintes
checkplus générales qui ne sont pas limitées à une seule ligne - La plupart des SGBDR n’ont pas de support complet pour les assertions, voire aucun support pour les assertions
Déclencheurs (Triggers)¶
- Les déclencheurs sont utilisés dans les bases de données actives
- Ils sont similaires aux événements dans une architecture orientée événements
- Un déclencheur exécute généralement une fonction sur un événement ou des événements spécifiques
- La fonction qu’il exécute est similaire à un gestionnaire d’événements
- par exemple, dans une page HTML, vous pouvez associer une fonction
JavaScript à un événement
onclicksur un bouton Do something
- par exemple, dans une page HTML, vous pouvez associer une fonction
JavaScript à un événement
- Les déclencheurs suivent la structure ECA pour définir des règles actives
- Event : signal (déclencheur) invoquant la règle
- Condition : test logique, détermine si l’action sera exécutée ou non
- Action : code ou fonction (en SQL, PL/SQL, ou un autre langage supporté) s’exécutant sur la base de données
- Le support des déclencheurs varie selon les SGBDR
Quand utiliser les déclencheurs¶
- Les déclencheurs peuvent être utilisés pour imposer des contraintes qui ne
peuvent pas être imposées autrement
- si les assertions ne sont pas supportées, alors une fonctionnalité similaire peut être obtenue avec des déclencheurs…
- mais les déclencheurs sont plus puissants que les assertions
- Les déclencheurs peuvent être utilisés pour la journalisation
- si vous voulez (ou devez) conserver des journaux de modifications, alors les déclencheurs peuvent aider
- normalement, lorsque des insertions, mises à jour et suppressions sont exécutées sur la base de données, aucune trace ne sera laissée
- créer des déclencheurs pour insérer des données dans une table de journal ou d’historique (ou des tables)
- plus de détails : https://en.wikipedia.org/wiki/Log_trigger
- Les déclencheurs peuvent être utilisés pour de nombreuses autres choses
- pour générer/mettre à jour des valeurs pour d’autres colonnes
- pour mettre à jour une table de statistiques
- pour auditer des données sensibles
- pour envoyer des emails aux DBA lors d’événements critiques
- pour implémenter d’autres règles métier
- De même que la programmation événementielle en JavaScript ou dans d’autres
langages de programmation, des fonctions doivent être associées à certains
événements
- les événements les plus courants sont :
INSERT,UPDATE, etDELETE - avec un modificateur (spécifié avant l’événement) :
BEFOREouAFTER - L’événement peut être déclenché pour chaque ligne ou pour l’ensemble de la
déclaration
- une seule instruction
INSERT,UPDATE, ouDELETEpeut s’appliquer à une ou plusieurs lignes - par défaut, nous obtenons un déclencheur au niveau de la déclaration
- si nous spécifions FOR EACH ROW, alors nous obtenons un déclencheur au niveau de la ligne
- une seule instruction
- les événements les plus courants sont :
- Par exemple, après avoir inséré les informations d’un nouvel employé dans une
table
employee, nous pourrions vouloir créer automatiquement un compte pour permettre au nouvel employé de se connecter au système de l’entreprise- la création d’un tel compte nécessiterait probablement l’insertion d’une
ligne dans une table
account - nous avons donc besoin d’un déclencheur
AFTER INSERTpour cela - notez que parfois, cette fonctionnalité est gérée par l’application frontale, et non par la base de données
- la création d’un tel compte nécessiterait probablement l’insertion d’une
ligne dans une table
-
Un autre exemple : nous pourrions avoir un déclencheur
BEFORE DELETEpour archiver les données supprimées importantes- nous pourrions insérer les données supprimées dans une autre table
- nous pourrions également enregistrer qui a supprimé les données et quand elles ont été supprimées
-
Malheureusement, les implémentations de déclencheurs varient selon les SGBD
- Certains ne supportent que des sous-ensembles de la norme, d’autres y apportent de petites modifications
- Dans PostgreSQL, les déclencheurs peuvent être créés avec la syntaxe ( simplifiée) suivante :
CREATE TRIGGER trigger_name
{BEFORE | AFTER | INSTEAD OF} {event [OR ...]}
ON table_name
[FOR [EACH] {ROW | STATEMENT}]
EXECUTE PROCEDURE trigger_function
- où
eventpeut êtreINSERT,UPDATE,DELETEouTRUNCATE -
Référez-vous à ces liens pour plus de détails :
-
Sur MySQL/MariaDB, la syntaxe de base est :
CREATE TRIGGER trigger_name
{BEFORE | AFTER} {INSERT | UPDATE| DELETE }
ON table_name FOR EACH ROW
trigger_body;
-
Référez-vous à ces liens pour plus de détails :
-
Sur Oracle, les déclencheurs peuvent être créés en utilisant la syntaxe suivante :
CREATE [OR REPLACE] TRIGGER trigger_name
{BEFORE | AFTER } triggering_event ON table_name
[FOR EACH ROW]
[FOLLOWS | PRECEDES another_trigger]
[ENABLE / DISABLE ]
[WHEN condition]
DECLARE
declaration statements
BEGIN
executable statements
EXCEPTION
exception_handling statements
END;
-
https://www.oracletutorial.com/plsql-tutorial/oracle-trigger/
-
Pour bien utiliser les déclencheurs, nous devons écrire des fonctions ou des procédures dans un certain langage de programmation
- PL/SQL (langage de programmation pour SQL) est supporté sous une certaine forme dans la plupart des bases de données relationnelles
- ou un autre langage de programmation supporté, tel que C
- PostgreSQL supporte les types définis par l’utilisateur (UDT) et les fonctions définies par l’utilisateur (UDF)
- Les UDF peuvent être définies en PL/SQL ou en C
- Les UDF peuvent être utilisées pour les déclencheurs
- d’autres langages de programmation supportent les langages de programmation de différentes manières