Tout ce qui s'apprend par cœur pour relier deux entités : le vocabulaire, les notations, la démarche du texte à la base, la syntaxe SQL, les pièges et une série de questions pour te tester.
Cette fiche rassemble ce qu'il faut savoir par cœur pour relier deux entités : découper les données, poser une association 1-N, la traduire en clé étrangère et interroger les deux tables ensemble. Elle ne contient pas d'exercice et peut s'imprimer seule. Les exemples portent sur une école : des élèves, des classes, et chaque élève appartient à une classe.
| Terme | En anglais | Définition |
|---|---|---|
| Redondance | 🇬🇧 redundancy | Un même fait écrit à plusieurs endroits d'une base. |
| Anomalie | 🇬🇧 anomaly | Problème qui apparaît quand on ajoute, modifie ou supprime des données dans une table qui mélange plusieurs choses. La base accepte l'opération, mais le résultat est incomplet ou contradictoire. On distingue les anomalies de modification (une ligne oubliée), d'insertion (impossible d'enregistrer une information seule) et de suppression (effacer une information en efface une autre). |
| Association | 🇬🇧 relationship | Lien entre deux entités. Son nom est un verbe conjugué à la 3ᵉ personne : appartient. On ne dit pas « relation ». |
| Schéma entité-association | 🇬🇧 entity-relationship diagram (ERD) | Dessin qu'on réalise pour analyser un domaine : entités dans des rectangles avec leurs attributs, associations dans des losanges nommés par un verbe, cardinalités de chaque côté. |
| MCD (modèle conceptuel de données) | 🇬🇧 conceptual data model | Description des entités, de leurs attributs et des associations qui les relient, sans se préoccuper du logiciel ; on la représente par un schéma entité-association. |
| Merise | — | Méthode française de conception de bases de données, qui fixe les règles du schéma entité-association : rectangles pour les entités, losanges pour les associations, cardinalités min-max. |
| Cardinalité | 🇬🇧 cardinality | Couple (minimum, maximum) écrit à côté d'une entité : à combien d'occurrences de l'autre entité une occurrence de cette entité peut être liée. |
| Association 1-N | 🇬🇧 one-to-many relationship | Association dont le maximum vaut 1 d'un côté et n de l'autre. |
| Clé étrangère | 🇬🇧 foreign key | Colonne qui contient la clé primaire d'une ligne d'une autre table. Elle fonctionne comme une adresse. |
| MLD (modèle logique de données) | 🇬🇧 logical data model | Traduction du MCD en liste de tables : chaque entité devient une table, chaque attribut une colonne, chaque association 1-N une clé étrangère. |
REFERENCES |
🇬🇧 foreign key constraint | Mot-clé SQL qui déclare qu'une colonne est une clé étrangère vers une autre table : fait référence à. |
PRAGMA foreign_keys |
🇬🇧 pragma | Réglage propre à SQLite qui active la vérification des clés étrangères. Désactivé par défaut, valable seulement pour la session en cours. |
| Intégrité référentielle | 🇬🇧 referential integrity | Contrainte qui garantit que chaque clé étrangère désigne une ligne qui existe vraiment. |
| Ligne orpheline | 🇬🇧 orphan row | Ligne dont la clé étrangère désigne une ligne qui n'existe pas, ou plus. |
| Produit cartésien | 🇬🇧 cartesian product | Toutes les combinaisons possibles entre les lignes de deux tables. Nombre de lignes : le produit des deux nombres de lignes. |
| Jointure | 🇬🇧 join | Assemblage des lignes de deux tables qui correspondent l'une à l'autre, selon une condition ON. |
| Alias de table | 🇬🇧 table alias | Surnom donné à une table dans une requête (FROM eleve e), utilisé pour préfixer les colonnes. |
LEFT JOIN |
🇬🇧 left join | Jointure qui garde toutes les lignes de la table de gauche, même sans correspondance ; les colonnes de droite valent alors NULL. |
Rappel des mots des autres niveaux : une entité est une chose dont on veut garder la trace ; une occurrence en est un exemplaire concret ; une contrainte est une règle que la base vérifie à chaque écriture (NOT NULL, UNIQUE, clé étrangère).
| Point | Convention | Exemple |
|---|---|---|
| Cardinalité | Merise min-max, écrite du côté de l'entité qu'elle décrit | ELEVE (0,1) —appartient— (0,n) CLASSE |
| Les quatre cardinalités | Entre parenthèses, n minuscule |
(0,1) (1,1) (0,n) (1,n) |
| Lecture | « un » + l'entité du côté où les chiffres sont écrits | « Un élève appartient au minimum à 0 classe et au maximum à 1 classe. » |
| Association | Un verbe conjugué à la 3ᵉ personne | appartient |
| Entité (MCD) | Singulier, MAJUSCULES | ELEVE |
| Table (base) | Singulier, minuscules, sans accent | eleve |
| Clé primaire | id |
classe.id |
| Clé étrangère | Table désignée + _id |
classe_id |
| Clé étrangère dans le MLD | # + colonne + flèche vers la colonne désignée |
#classe_id → classe.id |
| Placement | La clé étrangère va dans la table de l'entité qui porte le maximum 1 — celui qui n'en a qu'un garde l'adresse de l'autre. | classe_id dans eleve |
| Cardinalité | Se lit |
|---|---|
(0,1) |
au plus un, éventuellement aucun |
(1,1) |
exactement un |
(0,n) |
autant qu'on veut, éventuellement aucun |
(1,n) |
au moins un, autant qu'on veut |
MLD de l'école (clé primaire soulignée) :
ELEVE —appartient— CLASSE. Sans verbe, c'est souvent un attribut.ELEVE (0,1) —appartient— (0,n) CLASSE.PRAGMA foreign_keys = ON;CREATE TABLE pour la nouvelle table, ALTER TABLE … ADD COLUMN … REFERENCES … pour la colonne, puis UPDATE pour remplir les liens.FOREIGN KEY constraint failed et ne rien modifier.Déclarer une clé étrangère dans une nouvelle table ou dans une table existante :
CREATE TABLE eleve (
id INTEGER PRIMARY KEY,
nom TEXT NOT NULL,
classe_id INTEGER REFERENCES classe(id)
);
ALTER TABLE eleve ADD COLUMN classe_id INTEGER REFERENCES classe(id);
Activer, contrôler et vérifier les clés étrangères :
PRAGMA foreign_keys = ON; -- activer (pour la session en cours)
PRAGMA foreign_keys; -- 1 = activé, 0 = désactivé
PRAGMA foreign_key_check; -- liste les lignes dont la clé étrangère est invalide
Joindre deux tables, avec des alias :
SELECT e.prenom, e.nom, c.nom AS classe
FROM eleve e
JOIN classe c ON c.id = e.classe_id;
Garder aussi les lignes sans correspondance, ou les isoler :
SELECT e.prenom, e.nom, c.nom AS classe
FROM eleve e
LEFT JOIN classe c ON c.id = e.classe_id;
SELECT e.prenom, e.nom
FROM eleve e
LEFT JOIN classe c ON c.id = e.classe_id
WHERE c.id IS NULL;
Compter par groupe, groupes vides compris :
SELECT c.nom AS classe, COUNT(e.id) AS nb_eleves
FROM classe c
LEFT JOIN eleve e ON e.classe_id = c.id
GROUP BY c.nom;
Depuis Python :
conn = sqlite3.connect("mon-ecole-classes.db")
conn.execute("PRAGMA foreign_keys = ON")
conn.row_factory = sqlite3.Row
| Mot-clé | Traduction |
|---|---|
REFERENCES |
fait référence à |
ALTER TABLE … ADD COLUMN |
modifier la table … ajouter une colonne |
JOIN … ON |
joindre … sur |
LEFT JOIN |
jointure à gauche |
AS |
comme |
IS NULL |
est vide |
FOREIGN KEY constraint failed |
la contrainte de clé étrangère a échoué |
ambiguous column name |
nom de colonne ambigu |
Le (0,1) écrit à côté de ELEVE parle d'un élève et compte ses classes. Il ne veut pas dire « zéro ou un élève ». Parade : toujours formuler la phrase « Un élève … ».
La clé étrangère va du côté du maximum 1, jamais du côté du n. Une colonne eleve_id dans classe obligerait à écrire plusieurs élèves dans une seule case, ou à recopier la classe : retour à la redondance.
Sans PRAGMA foreign_keys = ON, SQLite accepte n'importe quelle valeur dans une clé étrangère et laisse supprimer des lignes encore désignées. Les lignes orphelines créées pendant ce temps restent dans la base quand on réactive le pragma. Il faut l'activer dans chaque logiciel et chaque programme, avant toute écriture.
FROM eleve, classe sans condition donne toutes les combinaisons : 12 × 3 = 36 lignes, sans message d'erreur. Symptôme : un résultat beaucoup trop gros, où chaque ligne se répète. Une condition ON fausse (ON c.id = e.id) donne aussi des lignes fausses sans erreur.
LEFT JOIN annulé par un WHEREUne condition du WHERE sur la table de droite (WHERE c.nom <> '4TTR') élimine les lignes où cette table vaut NULL, c'est-à-dire celles que le LEFT JOIN devait garder. Parade : ajouter OR c.id IS NULL.
4TRR ne provoque-t-elle aucun message d'erreur dans un tableau unique ?ELEVE (0,1) —appartient— (0,n) CLASSE.VEHICULE (1,1) —appartient— (0,n) CLIENT ?#classe_id → classe.id dans un MLD ?PRAGMA foreign_keys dans chaque programme ?SELECT * FROM eleve, classe; avec 12 élèves et 3 classes ? Comment s'appelle ce résultat ?JOIN ou LEFT JOIN ? Pourquoi ?B14 recopié sur la ligne de chacun des cinq élèves de 4TTR.4TRR n'existe pas : c'est une valeur de texte comme une autre.passe.(0,1), (1,1), (0,n) et (1,n).client_id va dans la table vehicule.classe_id est une clé étrangère qui désigne la colonne id de la table classe.FOREIGN KEY constraint failed.LEFT JOIN, parce qu'on veut voir aussi les élèves qui n'ont pas de correspondance dans la table classe. JOIN les ferait disparaître.