Suite du DDL (Data Definition Language)¶
Nous avons vu que :
- Le DDL permet de créer, modifier ou supprimer des objets de la base de données, comme des tables.
- Lorsqu'on crée une table, on doit indiquer le type de données pour chaque colonne (le domaine d'application)
- Selon le modèle relationnel, une table doit avoir une clé primaire
- Les tables doivent avoir des clés étrangères pour assurer les relations entre elles
Ainsi, lors de la création des tables dans une base de données, on utilise des clés et des contraintes pour garantir la cohérence, la fiabilité et la qualité des données.
Règle importante¶
Bien qu'il soit possible de créer des contraintes sans les nommer, les bonnes pratiques requiert de toujours nommer les contraintes de façon claire.
Pourquoi ?
-
Une contrainte peut facilement être modifiée ou supprimée au besoin
ALTER TABLE emprunt DROP CONSTRAINT pk_emprunt;Sinon on doit supprimer la colonne entière (et ses données) et la recréer (et ses données)
-
Une erreur déclenchée par une contrainte nommée est beaucoup plus claire
ORA-00001: unique constraint (PK_EMPRUNT) violatedAu lieu de
ORA-00001: unique constraint (SYS_C004892) violated???
Convention de nommage¶
-
Utiliser un préfixe explicite
Type de contrainte Préfixe Clé primaire pk_ Clé étrangère fk_ Clé secondaire / Unique uk_ Check ck_ Non nul nn_ -
Nommer la table
Si le champ n'a pas le nom de la table intégré
-
Nommer le champ
Si le champ ne possède pas et le nom de champ et le nom de la table
Exemples :
Pour le champ noEmploye de la table Employe, on veut créer la clé primaire :
noEmploye NUMBER(4) CONSTRAINT pk_noEmploye PRIMARY KEY
Ici, le champ contient le nom de la table, donc le préfixe + nom de champ est suffisant.
Pour le champ age de la table Client, on veut s'assurer que l'âge est au moins de 18 ans :
age NUMBER(2) CONSTRAINT ck_client_age CHECK (age > 18)
Ici, le champ age ne contient pas le nom de la table, donc la contrainte doit contenir le préfixe, le nom de la table et finalement le nom du champ.
Dans le cours!
Puisque dans le cours on exige que chaque champ soit nommé avec le nom de la table, les contraintes pourront être nommées avec le préfixe et le nom du champ.
1️⃣ Clé primaire (PRIMARY KEY)¶
La clé primaire identifie de façon unique chaque ligne d’une table.
Règles :
- Unique pour chaque ligne
- Obligatoire, jamais que cette information n'est nulle (implicite dans la clé primaire)
- Une seule clé primaire par table (constituée de une à plusieurs colonnes)
Exemples :
✏ Si la clé primaire n'est qu'une seule colonne :
CREATE TABLE etudiant (
noDA NUMBER(7) CONSTRAINT pk_etudiant PRIMARY KEY,
prenom VARCHAR2(50),
nom VARCHAR2(50),
date_naissance DATE,
courriel VARCHAR2(100),
date_inscription DATE
);
✏ Si la clé primaire s'applique sur plus d'une colonne :
CREATE TABLE emprunt (
numero_etudiant NUMBER(8),
numero_livre NUMBER(6),
date_emprunt DATE,
date_retour DATE,
CONSTRAINT pk_emprunt
PRIMARY KEY (numero_etudiant, numero_livre, date_emprunt)
);
2️⃣ Clé secondaire (clé unique)¶
Une clé secondaire est un champ qui :
- identifie aussi une ligne de façon unique
- n’est pas la clé primaire
- sera souvent utilisée pour des recherches
Exemples :
✏ Si la clé secondaire n'est qu'une seule colonne :
--Deux etudiants ne peuvent avoir le même courriel
CREATE TABLE etudiant (
noDA NUMBER(7) CONSTRAINT pk_etudiant PRIMARY KEY,
prenom VARCHAR2(50),
nom VARCHAR2(50),
date_naissance DATE,
courriel VARCHAR2(100) CONSTRAINT uk_etudiant_courriel UNIQUE,
date_inscription DATE
);
✏ Si la clé secondaire s'applique sur plus d'une colonne :
CREATE TABLE inscription (
numero_inscription NUMBER(8) CONSTRAINT pk_inscription PRIMARY KEY,
numero_etudiant NUMBER(7),
code_cours VARCHAR2(10),
session VARCHAR2(3),
date_inscription DATE,
CONSTRAINT uk_inscription_etudiant_cours_session
UNIQUE (numero_etudiant, code_cours, session)
);
3️⃣ Clé étrangère (FOREIGN KEY)¶
Une clé étrangère crée un lien entre deux tables.
Elle associe une clé primaire d'une table à un enregistrement d'une autre table.
Elle garantit que la valeur existe dans une autre table.
Exemples :
✏ Si la clé étrangère n'est qu'une seule colonne :
CREATE TABLE cours (
code_cours VARCHAR2(10) CONSTRAINT pk_cours PRIMARY KEY,
nom_cours VARCHAR2(100),
ponderation VARCHAR2(5),
id_departement NUMBER(5) CONSTRAINT fk_cours_departement
REFERENCES departement
);
✏ Si la clé étrangère fait référence à une table dont la clé primaire est composite (plus d'une colonne) :
CREATE TABLE participation_evenement (
id_evenement NUMBER(5),
id_membre NUMBER(8),
annee NUMBER(4),
date_inscription DATE,
CONSTRAINT pk_participation
PRIMARY KEY (id_membre, id_evenement, annee),
CONSTRAINT fk_participation_evenement
FOREIGN KEY (id_evenement, annee)
REFERENCES evenement(id_evenement, annee)
);
4️⃣ Contrainte NOT NULL¶
La contrainte NOT NULL oblige une colonne à toujours contenir une valeur.
Exemple :
nom VARCHAR2(50) NOT NULL
Le nom doit toujours être fourni.
Comment l'écrire de façon complète :
CREATE TABLE cours (
code_cours VARCHAR2(10) CONSTRAINT pk_cours PRIMARY KEY,
nom_cours VARCHAR2(100) CONSTRAINT nn_nom_cours NOT NULL,
ponderation VARCHAR2(5),
id_departement NUMBER(5) CONSTRAINT fk_cours_departement
REFERENCES departement
);
Pour modifier la contrainte, NOT NULL est la seule qui peut être modifiée sans être nommée :
ALTER TABLE nom_table
MODIFY nom_colonne NULL;
- NULL indique que la colonne peut maintenant contenir des valeurs NULL
- La colonne doit déjà exister dans la table
- Il n’est pas nécessaire de connaître le nom de la contrainte NOT NULL.
- Si la colonne contient déjà des données, Oracle autorise la modification tant que les lignes existantes respectent la nouvelle règle (ici aucune restriction, puisque NULL est autorisé).
5️⃣ Contraintes d’intégrité CHECK¶
Les contraintes CHECK ajoute un niveau de validation sur les données, en plus de NOT NULL et du type de données.
Elles assurent que les valeurs entrées respectent des conditions précises.
Exemples :
✏ Si la contrainte s'applique sur une colonne :
CREATE TABLE abonnements (
...
type_abonnement VARCHAR2(20) CONSTRAINT ck_type_abonnement
CHECK (type_abonnement IN ('mensuel', 'trimestriel', 'annuel')),
...
);
Ou encore :
CREATE TABLE membres (
...
age NUMBER(2) CONSTRAINT ck_membre_age CHECK (age > 18),
...
);
✏ Si la contrainte s'applique sur plus d'une colonne :
CREATE TABLE reservation_hotel (
id_reservation NUMBER CONSTRAINT pk_reservation_hotel PRIMARY KEY,
nom_client VARCHAR2(50) NOT NULL,
date_arrivee DATE,
date_depart DATE,
CONSTRAINT ck_dates_reservation CHECK (date_depart > date_arrivee)
);
6️⃣ Valeur par défaut (DEFAULT)¶
L'orsqu'une valeur par défaut est indiquée, elle est automatiquement utilisée si aucune valeur n’est fournie lors de l'insertion de données.
Exemple :
CREATE TABLE reservation_hotel (
id_reservation NUMBER CONSTRAINT pk_reservation_hotel PRIMARY KEY,
nom_client VARCHAR2(50) NOT NULL,
date_arrivee DATE DEFAULT SYSDATE,
date_depart DATE DEFAULT SYSDATE + 2
);
On peut aussi indiquer que la valeur par défaut sera la prochaine valeur d'une séquence :
Exemple :
CREATE TABLE reservation_hotel (
id_reservation NUMBER
DEFAULT seq_reservation.NEXTVAL
CONSTRAINT pk_reservation_hotel PRIMARY KEY,
nom_client VARCHAR2(50) NOT NULL,
date_arrivee DATE DEFAULT SYSDATE,
date_depart DATE DEFAULT SYSDATE + 2
);
🆘 Ajouter, supprimer, modifier des contraintes¶
Une fois qu'une table a été créée, il est possible de modifier les contraintes si les données respectent les modifications.
Ajout d'une contrainte
ALTER TABLE nomTable
ADD CONSTRAINT nomContrainte contrainteAjoutee;
Exemples :
ALTER TABLE etudiant
ADD CONSTRAINT uk_etudiant_email UNIQUE (email);
ALTER TABLE etudiant
ADD CONSTRAINT ck_client_age CHECK (age > 0);
Suppression d'une contrainte
ALTER TABLE nomTable
DROP nomContrainte;
Pour les contrainte NOT NULL non nommée :
ALTER TABLE nom_table
MODIFY nom_colonne NULL;
Pas de modification
En Oracle, il n’est pas possible de modifier directement une contrainte existante (comme on pourrait modifier une colonne).
💡 La méthode standard consiste à :
- Supprimer la contrainte existante
- Ajouter une nouvelle contrainte avec les nouvelles règles