Les contraintes d'intégrité et les séquences sont des éléments essentiels pour garantir la cohérence et la
stabilité des données dans les systèmes de gestion de bases de données (SGBD).
Objectif du cours : Comprendre le rôle et l'importance des contraintes dans la gestion des erreurs et des
incohérences, et des séquences dans la gestion des identifiants uniques.
Contexte et importance des contraintes d'intégrité
Les contraintes d'intégrité sont des règles imposées sur les données pour garantir leur validité.
Elles assurent que les données sont conformes aux règles métiers (par exemple, un âge ne peut pas être
négatif, un email doit être unique).
Elles empêchent l'insertion, la modification ou la suppression de données incorrectes.
Les contraintes sont définies dans le SGBD pour s'assurer que toutes les opérations sur les données
respectent ces règles.
Lorsqu'une contrainte est violée, l'opération est annulée et un message d'erreur est retourné.
Cela garantit que les erreurs humaines ou les bugs dans les programmes ne corrompent pas la base de
données.
Types de contraintes dans SQL
NOT NULL : Empêche l'enregistrement de valeurs nulles dans une colonne. Exemple : un champ "nom" ne
peut pas être vide dans une table "Personne".
UNIQUE : Assure que toutes les valeurs dans une colonne sont uniques. Exemple : aucune adresse
email ne doit être dupliquée dans une table "Utilisateurs".
PRIMARY KEY : Définit une ou plusieurs colonnes comme clé primaire, garantissant l'unicité et
servant d'identifiant pour chaque ligne. Exemple : une colonne "id" dans une table "Personne".
FOREIGN KEY : Garantit la validité des relations entre plusieurs tables en établissant un lien
entre une clé primaire et une clé étrangère. Exemple : la colonne "id_personne" dans une table
"Réservations" référant à la clé primaire "id" dans une table "Personne".
CHECK : Vérifie qu'une condition logique est respectée. Exemple : un champ "âge" doit toujours être
supérieur ou égal à zéro.
Contrainte multi-colonnes
Les contraintes peuvent impliquer plusieurs colonnes, comme les clés uniques composées.
Exemple : Supposons que nous souhaitions garantir qu'une combinaison de deux colonnes soit unique.
create table Employe (
id integer primary key,
prenom varchar(50),
nom varchar(50),
email varchar(100),
unique (prenom, nom)
);
Explication : Cet exemple impose qu'une combinaison de "prenom" et "nom" soit unique dans la table "Employe".
Cela peut être utilisé pour éviter des doublons où des personnes auraient le même prénom et nom.
Mécanismes internes des contraintes
Les contraintes telles que les clés primaires et les clés uniques reposent souvent sur des index
sous-jacents dans le SGBD.
Ces index permettent de garantir l'unicité de manière rapide et efficace, mais peuvent aussi impacter les
performances sur des tables de grande taille.
Les contraintes comme CHECK et FOREIGN KEY peuvent être implémentées à l'aide de triggers automatiques
au niveau de la base de données.
Remarque : Bien que ces contraintes améliorent la sécurité et la fiabilité des données, il est important de
prendre en compte leur impact sur les performances, surtout pour les opérations massives d'insertion ou de
modification.
Gestion des violations de contraintes
Lorsqu'une contrainte est violée, une exception est levée et l'opération échoue.
Les SGBD permettent de gérer ces erreurs avec des transactions qui peuvent être annulées en cas de
violation.
Exemple : Utilisation d'une transaction pour vérifier des conditions avant insertion.
begin transaction;
insert into Personne (id, nom, age, email)
values (seq_personne.nextval, 'Alice', -25, 'alice@example.com'); -- échoue
rollback; -- annule l'opération
Explication : Dans cet exemple, la tentative d'insertion échoue en raison de la contrainte CHECK sur l'âge.
L'utilisation d'une transaction permet d'annuler automatiquement toute modification de la base de données.
Contraintes côté application vs côté SGBD
Les contraintes peuvent également être implémentées côté application, par exemple en Java, pour garantir
la cohérence des données avant qu'elles ne soient envoyées au SGBD.
Cependant, les contraintes dans le SGBD offrent une garantie supplémentaire, car elles sont exécutées au
niveau de la base et ne dépendent pas de la qualité du code de l'application.
Exemple : Validation de la syntaxe d'une adresse email dans une application Java avant de l'insérer dans une
base de données. Cette validation est utile, mais elle ne remplace pas une contrainte UNIQUE dans la base.
Exemple : Contrainte NOT NULL
insert into Personne (id, nom, age, email)
values (1, null, 25, 'example@example.com'); -- Échoue à cause de NOT NULL
Explication : Cet exemple montre comment une tentative d'insertion échoue parce que la colonne "nom" ne peut
pas être nulle en raison de la contrainte NOT NULL.
Exemple de contraintes sur une table Personne
create table Personne (
id integer primary key,
nom varchar(50) not null,
age integer check (age >= 0),
email varchar(100) unique
);
Explication : Cette table "Personne" impose des contraintes pour garantir que chaque personne a un
identifiant unique, un nom obligatoire, un âge positif, et une adresse email unique.
Exemple : Clé étrangère avec suppression en cascade
create table Commande (
id_commande integer primary key,
id_client integer,
foreign key (id_client) references Client(id)
on delete cascade
);
delete from Client where id = 1; -- supprime également les commandes liées
Explication : Ici, la suppression d'un client dans la table "Client" entraîne la suppression automatique des
commandes associées dans la table "Commande" grâce à l'option on delete cascade.
Exemple : Cascade sur mise à jour
create table Commande (
id_commande integer primary key,
id_client integer,
foreign key (id_client) references Client(id)
on update cascade on delete cascade
);
update Client
set id = 2 where id = 1; -- met également à jour l'id dans la table "Commande"
Explication : Ici, toute mise à jour de la colonne "id" dans la table "Client" sera répercutée
automatiquement dans la table "Commande" grâce à l'option on update cascade.
Exemple : Contrainte CHECK complexe
create table Employe (
id integer primary key,
salaire decimal check (salaire > 0 and salaire < 10000)
);
Explication : Cette contrainte garantit que le salaire des employés est compris entre 0 et 10 000, empêchant
l'insertion de valeurs négatives ou excessivement élevées.
Principe des séquences
Les séquences sont utilisées pour générer automatiquement des identifiants uniques dans une base de
données.
Elles garantissent que chaque nouvel enregistrement obtient une valeur unique, ce qui est essentiel pour
les clés primaires.
Dans les systèmes multi-utilisateurs, elles permettent d'éviter les conflits d'identifiants lors de
l'insertion simultanée de données.
Les séquences sont créées avec un ordre SQL spécifique et peuvent être utilisées dans des commandes
d'insertion pour générer automatiquement de nouveaux identifiants.
Paramètres avancés des séquences
Les séquences peuvent être paramétrées avec différents attributs pour répondre aux besoins spécifiques.
Par exemple, les valeurs générées peuvent avoir un intervalle défini, un cycle ou une limite maximale.
create sequence seq_personne
start with 100
increment by 10
maxvalue 1000
cycle;
Explication : Cette séquence commence à 100, incrémente de 10 à chaque appel, et reprend à 100 lorsque la
valeur maximale de 1000 est atteinte (grâce à l'option cycle).
Exemples d'ordres SQL pour les séquences
create sequence seq_personne;
select seq_personne.nextval; -- génère la prochaine valeur de la séquence
select seq_personne.currval; -- renvoie la dernière valeur générée
Explication : L'ordre nextval génère la prochaine valeur dans la séquence, tandis que currval renvoie la
dernière valeur générée par nextval. Ces commandes sont essentielles pour l'insertion d'enregistrements avec
des identifiants uniques dans des systèmes multi-utilisateurs.
Explication : Lors de l'insertion d'une nouvelle personne dans la table "Personne", une nouvelle valeur de
séquence est générée pour l'identifiant unique "id". Cette méthode assure que chaque personne a un identifiant
distinct.
Gestion des permissions et confidentialité
Dans un SGBD, il est essentiel de gérer les permissions pour protéger les données sensibles.
Les permissions permettent de restreindre l'accès aux séquences, tables, et autres objets de la base de
données à des utilisateurs autorisés uniquement.
Cette gestion fine des droits d'accès renforce la sécurité des données, empêchant les modifications ou
accès non autorisés.
Exemple : Donner le droit à un autre utilisateur d'utiliser une séquence pour insérer des données dans la
table "Personne".
Contraintes temporelles et transactions
Les contraintes temporelles sont des règles qui dépendent du moment où une opération est effectuée.
Elles sont souvent utilisées dans des systèmes nécessitant une gestion précise des périodes de validité
des données.
Les transactions assurent que les contraintes sont respectées de bout en bout en garantissant l'atomicité
des opérations (tout ou rien).
Explication : Cet exemple impose que la date de fin d'un contrat soit toujours postérieure à la date de
début, une contrainte essentielle pour garantir la cohérence des informations temporelles.
Compétences à acquérir
Savoir analyser le comportement des ordres SQL en présence de contraintes et de séquences.
Être capable d'écrire des ordres SQL adéquats pour modéliser les contraintes du cahier des charges d'une
application.
Connaître les limites du langage SQL et savoir quand utiliser des approches complémentaires, comme Java,
pour pallier ces limites.
Démonstration
Présentation pratique des contraintes sur des tables, de l'utilisation des séquences et de la gestion des
permissions pour illustrer concrètement les concepts abordés.