Encore un peu de théorie, désolé ! On va passer étape par étape sur la création d'une structure MANY-TO-MANY. Prêt ?
La relation MANY-TO-MANY entre les étudiants et les cours ne peut pas être représentée directement dans une seule table. Un étudiant peut être inscrit à plusieurs cours, et un cours peut être suivi par plusieurs étudiants en même temps.
Pour gérer ça, on crée une table intermédiaire enrollments qui va stocker les infos sur les inscriptions, c'est-à-dire quelles paires étudiant-cours existent. Ça nous permet non seulement d'assurer l'intégrité des données, mais aussi d'ajouter facilement des fonctionnalités, genre la date d'inscription.
À quoi ressemble la table enrollments ?
Tu sais déjà que la table enrollments va être le point central entre les tables students et courses. Voilà sa structure :
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY, -- ID unique de l'inscription
student_id INT REFERENCES students(student_id), -- Clé étrangère vers la table students
course_id INT REFERENCES courses(course_id), -- Clé étrangère vers la table courses
enrollment_date DATE DEFAULT CURRENT_DATE -- Quand l'étudiant a été inscrit au cours
);
On va décortiquer chaque ligne :
enrollment_id: C'est l'identifiant unique de chaque inscription. Chaque étudiant inscrit à un cours doit être identifié de façon unique.student_id: Indique quel étudiant est inscrit. C'est une clé étrangère qui pointe vers la tablestudents(colonnestudent_id).course_id: Indique à quel cours l'étudiant est inscrit. Cette colonne est liée à la tablecourses(colonnecourse_id).enrollment_date: Un petit plus sympa, ça montre la date d'inscription. On utiliseDEFAULT CURRENT_DATEpour mettre automatiquement la date du jour lors de la création de l'enregistrement.
Création des tables students et courses
Avant d'aller plus loin, vérifions qu'on a déjà les tables students et courses :
CREATE TABLE students (
student_id SERIAL PRIMARY KEY, -- Identifiant unique de l'étudiant
name TEXT NOT NULL, -- Nom de l'étudiant
email TEXT NOT NULL UNIQUE -- Email de l'étudiant, pour éviter les doublons
);
CREATE TABLE courses (
course_id SERIAL PRIMARY KEY, -- Identifiant unique du cours
title TEXT NOT NULL, -- Titre du cours
description TEXT, -- Description du cours
start_date DATE -- Date de début du cours
);
Remarque, ici on a ajouté des détails utiles, genre un email unique pour chaque étudiant et une description du cours dans la table courses.
On relie tout ensemble
Maintenant que nos tables sont prêtes, créons la table enrollments :
CREATE TABLE enrollments (
enrollment_id SERIAL PRIMARY KEY, -- ID unique de l'inscription
student_id INT NOT NULL REFERENCES students(student_id), -- Clé étrangère
course_id INT NOT NULL REFERENCES courses(course_id), -- Clé étrangère
enrollment_date DATE DEFAULT CURRENT_DATE -- Date d'inscription
);
Insertion de données dans les tables
Ok, les tables sont prêtes, mais elles s'ennuient sans données. Ajoutons quelques étudiants, des cours et leurs inscriptions :
Insertion des étudiants :
INSERT INTO students (name, email)
VALUES
('Alex Lin', 'alex.lin@example.com'),
('Maria Chi', 'maria.chi@example.com'),
('Otto Song', 'otto.song@example.com');
Insertion des cours :
INSERT INTO courses (title, description, start_date)
VALUES
('Bases de la programmation', 'Cours pour les débutants en programmation.', '2023-11-01'),
('Bases de données', 'On apprend SQL et les bases de données relationnelles.', '2023-11-15'),
('Développement web', 'Création de sites et d\'applications web.', '2023-12-01');
Insertion des inscriptions :
INSERT INTO enrollments (student_id, course_id)
VALUES
(1, 1), -- Alex Lin sur "Bases de la programmation"
(1, 2), -- Alex Lin sur "Bases de données"
(2, 2), -- Maria Chi sur "Bases de données"
(3, 3); -- Otto Song sur "Développement web"
Ici, student_id et course_id correspondent aux identifiants dans les tables concernées.
On vérifie les liens avec des requêtes
Récupérer toutes les inscriptions :
SELECT e.enrollment_id, s.name AS student_name, c.title AS course_title, e.enrollment_date
FROM enrollments e
JOIN students s ON e.student_id = s.student_id
JOIN courses c ON e.course_id = c.course_id;
Résultat :
| enrollment_id | student_name | course_title | enrollment_date |
|---|---|---|---|
| 1 | Alex Lin | Bases de la programmation | 2023-11-01 |
| 2 | Alex Lin | Bases de données | 2023-11-01 |
| 3 | Maria Chi | Bases de données | 2023-11-01 |
| 4 | Otto Song | Développement web | 2023-11-01 |
Exercice pour t'entraîner
Essaie d'ajouter encore quelques étudiants et cours, puis inscris-les dans la table enrollments. Par exemple, ajoute le cours "Apprentissage automatique" et inscris-y 1 ou 2 étudiants. Utilise la requête ci-dessus pour vérifier le résultat.
Erreurs classiques possibles
Quand tu bosses avec des clés étrangères et des tables intermédiaires, il y a quelques pièges classiques :
Absence d'enregistrement dans la table parente : Si tu essaies d'ajouter une ligne dans
enrollmentsavec unstudent_idoucourse_idqui n'existe pas dansstudentsoucourses, tu vas avoir une erreur. La clé étrangère veille au grain.Violation de l'intégrité des données lors de la suppression : Si tu supprimes un étudiant ou un cours déjà utilisé dans
enrollmentssans avoir misON DELETE CASCADE, ça va planter.Doublons : Fais gaffe à ne pas inscrire un étudiant plusieurs fois au même cours, sauf si c'est prévu dans la logique métier.
Voilà, tu as maintenant un modèle fonctionnel pour représenter une relation MANY-TO-MANY entre étudiants et cours dans PostgreSQL. Cette structure est super courante dans les applis réelles, genre les systèmes de gestion d'apprentissage, les CRM et plein d'autres. On passe à la prochaine leçon !
GO TO FULL VERSION