Panorama Médiathèque — mise en situation
Pourquoi commencer un cours de Machine Learning par du SQL ?
Section titled “Pourquoi commencer un cours de Machine Learning par du SQL ?”Avant d’entraîner un modèle, il faut des données — et ces données dorment presque toujours dans une base relationnelle. Savoir en extraire exactement ce dont on a besoin, sans tout rapatrier en mémoire pour filtrer « à la main » en Python, est une compétence que tout profil data (analyst, scientist, ML engineer) utilise quotidiennement. Ce module traite le SQL comme un outil d’analyse de données, pas seulement comme un langage de stockage.
Le scénario
Section titled “Le scénario”Vous êtes analyste de données pour le compte d’une médiathèque municipale. Sa directrice a deux questions concrètes :
- Quelle catégorie de documents (livres, BD, DVD, jeux de société) faut-il renforcer en nombre d’exemplaires ?
- Quels adhérents inviter en priorité à une soirée de lancement ?
Aucune des deux questions n’a de réponse en une seule requête : il va falloir décomposer chaque question en une suite de petites requêtes vérifiables, puis assembler les résultats en une recommandation argumentée. C’est exactement la démarche d’un analyste de données face à une question business ambiguë.
Le schéma de données
Section titled “Le schéma de données”Trois tables, reliées par des clés étrangères :
CREATE TABLE adherents ( id INTEGER PRIMARY KEY, prenom TEXT NOT NULL, nom TEXT NOT NULL, email TEXT NOT NULL UNIQUE, ville TEXT NOT NULL);
CREATE TABLE documents ( id INTEGER PRIMARY KEY, reference TEXT NOT NULL UNIQUE, titre TEXT NOT NULL, categorie TEXT NOT NULL CHECK (categorie IN ('livre', 'bd', 'dvd', 'jeu_de_societe')), nombre_exemplaires INTEGER NOT NULL, tarif_retard REAL NOT NULL);
CREATE TABLE emprunts ( id INTEGER PRIMARY KEY, adherent_id INTEGER NOT NULL REFERENCES adherents(id), document_id INTEGER NOT NULL REFERENCES documents(id), date_emprunt TEXT NOT NULL, date_retour_prevue TEXT NOT NULL, statut TEXT NOT NULL CHECK (statut IN ('en_cours', 'rendu', 'en_retard')));Trois contraintes méritent d’être commentées :
UNIQUEsuremailetreference: garantit qu’on ne peut pas créer deux fois le même adhérent ou le même document.REFERENCES(clé étrangère) : un emprunt ne peut pointer que vers un adhérent et un document qui existent réellement.CHECK: restreint une colonne texte à une liste de valeurs autorisées — utile pour éviter des statuts fantaisistes comme"peut-être rendu".
On peut vérifier qu’une contrainte CHECK fonctionne réellement en tentant d’insérer une valeur interdite :
try: cur.execute( "INSERT INTO emprunts VALUES (99, 1, 1, '2026-01-01', '2026-01-15', 'perdu')" ) print("ERREUR: aurait du etre rejete")except sqlite3.IntegrityError as e: print("Rejet confirme:", e)Rejet confirme: CHECK constraint failed: statut IN ('en_cours', 'rendu', 'en_retard')Ce moteur SQLite tourne en mémoire (sqlite3.connect(":memory:")), recréé à chaque exécution : aucun fichier n’est nécessaire pour suivre ce cours, et le script est idempotent (on peut le relancer autant de fois qu’on veut sans erreur de doublon).
Prochaine étape
Section titled “Prochaine étape”👉 Requêtes de base : SELECT, WHERE, ORDER BY, LIMIT
Junior TSAFACK – 12/09/2026