Exercice 1 : QCM
Pour chaque question, une seule réponse est correcte.
1. Dans le modèle relationnel, comment appelle-t-on une colonne d’une table ?
- A. Un enregistrement
- B. Une relation
- C. Un attribut
- D. Une clé
Correction publiée après la séance.
2. Quel est le rôle d’une clé primaire ?
- A. Chiffrer les données de la table
- B. Trier automatiquement les enregistrements
- C. Relier deux tables entre elles
- D. Identifier de manière unique chaque enregistrement
Correction publiée après la séance.
3. Quelle requête SQL permet de sélectionner tous les employés dont le salaire est supérieur à 3000 ?
- A.
SELECT * FROM employes WHERE salaire > 3000 - B.
SELECT * FROM employes IF salaire > 3000 - C.
SELECT * WHERE salaire > 3000 FROM employes - D.
SELECT salaire > 3000 FROM employes
Correction publiée après la séance.
4. Parmi ces ordres SQL, lequel est un ordre LDD (langage de définition des données) ?
- A.
SELECT * FROM employes - B.
INSERT INTO employes VALUES (...) - C.
CREATE TABLE employes (...) - D.
UPDATE employes SET salaire = 2000
Correction publiée après la séance.
5. Dans le modèle relationnel, qu’est-ce qu’une clé étrangère ?
- A. Un attribut qui ne peut jamais être
NULL - B. Un attribut qui identifie de manière unique un enregistrement dans sa propre table
- C. Un attribut qui contient des données chiffrées
- D. Un attribut qui référence la clé primaire d’une autre table
Correction publiée après la séance.
Exercice 2 : lire et comprendre un schéma relationnel (exercice guidé)
Une médiathèque utilise la base de données suivante :
- Livres(id_livre, titre, auteur, annee)
- Adherents(num_adherent, nom, prenom)
- Emprunts(id_emprunt, #id_livre, #num_adherent, date_emprunt, date_retour)
Les attributs soulignés sont les clés primaires. Les attributs précédés de # sont les clés étrangères.
a) Combien de tables comporte ce schéma ? Pour chaque table, donnez le nombre d’attributs.
Indice
Une table par ligne du schéma ; ses attributs sont listés entre parenthèses, clés comprises.
b) Quelle est la clé primaire de la table Emprunts ? Quelles sont ses clés étrangères ?
Indice
La clé primaire est soulignée ; les clés étrangères sont précédées de #.
c) Un adhérent dont le num_adherent est 42 souhaite emprunter un livre dont le id_livre est 7. Quel attribut de la table Emprunts contiendra la valeur 42 ? Quel attribut contiendra 7 ?
Indice
Dans Emprunts, chaque clé étrangère reprend la clé primaire de la table qu’elle désigne : laquelle renvoie aux adhérents, laquelle aux livres ?
d) Est-il possible d’insérer dans Emprunts une ligne avec id_livre = 999 si aucun livre n’a cet identifiant dans la table Livres ? Justifiez en citant la contrainte concernée.
Indice
Une clé étrangère doit toujours désigner une ligne qui existe dans la table référencée : comment s’appelle cette contrainte ?
e) Deux emprunts peuvent-ils avoir le même id_emprunt ? Justifiez.
Indice
id_emprunt est la clé primaire : quelle propriété doit-elle vérifier ?
Correction publiée après la séance.
Exercice 3 : requêtes SELECT (WHERE, ORDER BY, DISTINCT, agrégation)
On considère la table Produits suivante :
| id | nom | categorie | prix | stock |
|---|---|---|---|---|
| 1 | Cahier A4 | Papeterie | 2.50 | 150 |
| 2 | Stylo bleu | Papeterie | 1.20 | 300 |
| 3 | Clé USB 32 Go | Informatique | 8.90 | 45 |
| 4 | Cartouche encre | Informatique | 25.00 | 20 |
| 5 | Classeur | Papeterie | 3.80 | 80 |
| 6 | Souris sans fil | Informatique | 15.50 | 60 |
| 7 | Colle | Papeterie | 1.50 | 200 |
| 8 | Casque audio | Informatique | 35.00 | 15 |
Écrivez les requêtes SQL pour chacune des questions suivantes.
Indice
Une requête a la forme SELECT colonnes FROM table WHERE condition ORDER BY colonne;, et l’on retire les clauses inutiles.
a) Afficher le nom et le prix de tous les produits de la catégorie « Informatique ».
Indice
La condition porte sur la colonne categorie ; une chaîne s’écrit entre apostrophes, 'Informatique'.
b) Afficher les noms et prix des produits dont le prix est inférieur à 5 euros, triés par prix croissant.
Indice
WHERE prix < 5, puis ORDER BY prix : l’ordre croissant est l’ordre par défaut.
c) Afficher les différentes catégories présentes dans la table (chaque catégorie ne doit apparaître qu’une seule fois).
Indice
Le mot-clé DISTINCT, placé juste après SELECT, supprime les doublons.
d) Combien de produits ont un stock inférieur à 50 ?
Indice
COUNT(*) compte les lignes qui vérifient la condition du WHERE.
e) Quel est le prix moyen de tous les produits de la table ?
Indice
La fonction d’agrégation AVG calcule la moyenne d’une colonne.
f) Afficher le nom et le prix du produit le plus cher.
Indice
Trier par prix décroissant (DESC) et ne garder que la première ligne avec LIMIT 1 ; autre méthode, comparer le prix au résultat de la sous-requête SELECT MAX(prix) FROM Produits.
Correction publiée après la séance.
Exercice 4 : comprendre les jointures (exercice guidé)
On considère deux petites tables :
Eleves :
| id_eleve | nom | prenom | id_classe |
|---|---|---|---|
| 1 | Dupont | Marie | 101 |
| 2 | Martin | Lucas | 102 |
| 3 | Leroy | Emma | 101 |
Classes :
| id_classe | nom_classe | salle |
|---|---|---|
| 101 | Terminale A | B204 |
| 102 | Terminale B | C112 |
On souhaite afficher, pour chaque élève, son nom et le nom de sa classe. Il faut donc combiner les informations des deux tables : c’est une jointure.
a) Quel attribut est commun aux deux tables et permet de les relier ?
Indice
Chercher le nom de colonne présent dans les deux tables.
b) Pour l’élève Marie Dupont, son id_classe vaut 101. Dans la table Classes, quelle ligne correspond à id_classe = 101 ? Quel est le nom de sa classe ?
Indice
Lire la ligne de Classes dont la première colonne vaut 101.
c) Faites le même travail pour les deux autres élèves : recopiez et complétez le tableau suivant.
| nom | prenom | nom_classe | salle |
|---|---|---|---|
| Dupont | Marie | … | … |
| Martin | Lucas | … | … |
| Leroy | Emma | … | … |
Indice
Même démarche pour chaque élève : son id_classe désigne une ligne de Classes.
d) Voici la requête SQL qui réalise cette jointure :
SELECT Eleves.nom, Eleves.prenom, Classes.nom_classe
FROM Eleves
JOIN Classes ON Eleves.id_classe = Classes.id_classe;
Identifiez dans cette requête : la clause qui combine les deux tables ; la condition qui établit la correspondance.
Indice
La clause est introduite par JOIN ; la condition suit le mot ON.
e) Écrivez une requête qui affiche le prénom des élèves de la salle B204.
Indice
Reprendre la jointure de la question d) et ajouter une condition WHERE sur la colonne salle de la table Classes.
f) Combien d’élèves sont en Terminale A ? Écrivez la requête.
Indice
Même jointure, avec COUNT(*) et une condition sur nom_classe.
Correction publiée après la séance.
Exercice 5 : insertion, modification, suppression et contraintes
On reprend les tables de l’exercice 4 (Eleves et Classes).
a) Écrivez l’ordre SQL pour insérer une nouvelle classe : Terminale C, salle A308, identifiant 103.
Indice
INSERT INTO Classes VALUES (...);, avec les valeurs dans l’ordre des colonnes de la table.
b) Écrivez l’ordre SQL pour inscrire un nouvel élève : Paul Petit, identifiant 4, dans la classe 103.
Indice
Même instruction pour la table Eleves : identifiant, nom, prénom, puis id_classe.
c) Lucas Martin change de classe : il passe en Terminale A (id_classe = 101). Écrivez la requête de modification.
Indice
UPDATE Eleves SET colonne = valeur WHERE condition; : la condition désigne Lucas Martin, par exemple par son id_eleve.
d) On souhaite supprimer la classe « Terminale B » (id_classe = 102). Après la modification de la question c), est-ce possible sans violer de contrainte ? Justifiez.
Indice
Après la question c), un élève appartient-il encore à la classe 102 ? Une ligne ne peut être supprimée que si aucune clé étrangère ne la désigne.
e) Que se passerait-il si l’on tentait d’insérer un élève avec id_classe = 999, sachant qu’aucune classe n’a cet identifiant ? Quelle contrainte serait violée ?
Indice
Revoir la question d) de l’exercice 2.
Correction publiée après la séance.
Exercice 6 : anomalies dans une base mal conçue
Un magasin de vélos stocke toutes ses informations dans une seule table :
| id_vente | client | telephone_client | velo | marque | prix | date_vente |
|---|---|---|---|---|---|---|
| 1 | Alice Dupont | 0612345678 | VTT Sport 27.5 | Trek | 899 | 2025-09-15 |
| 2 | Bob Martin | 0698765432 | Vélo ville 28 | B’Twin | 349 | 2025-09-16 |
| 3 | Alice Dupont | 0612345678 | Vélo route carbone | Trek | 2499 | 2025-09-20 |
| 4 | Alice Dupont | 0612340000 | Casque urbain | B’Twin | 45 | 2025-10-01 |
a) Alice Dupont apparaît dans trois lignes. Son numéro de téléphone est-il le même partout ? Quel problème cela pose-t-il ?
Indice
Comparer les trois lignes d’Alice : quelle information est recopiée plusieurs fois, et que se passe-t-il si une seule copie est modifiée ?
b) Supposons que le magasin cesse de vendre le modèle « Vélo ville 28 ». Si l’on supprime la ligne 2, quelles informations perd-on en plus du vélo ? Pourquoi est-ce problématique ?
Indice
La ligne 2 est la seule où figure Bob Martin : que devient-il après la suppression ?
c) Le magasin souhaite ajouter un nouveau vélo (VTT Enfant 24) qu’il n’a encore jamais vendu. Peut-on ajouter ce vélo dans la table sans créer de vente fictive ? Pourquoi ?
Indice
Une ligne de cette table décrit une vente : quelles colonnes resteraient vides pour un vélo jamais vendu ?
d) Comment appelle-t-on chacun de ces trois problèmes dans le vocabulaire des bases de données ?
Indice
Ce sont trois anomalies, nommées d’après l’opération qui les provoque : la modification, la suppression et l’insertion.
e) Proposez un schéma relationnel avec plusieurs tables qui résout ces anomalies. Précisez les clés primaires et les clés étrangères.
Indice
Séparer ce qui décrit un client, ce qui décrit un vélo et ce qui décrit une vente : la table des ventes relie les deux autres par des clés étrangères.
Correction publiée après la séance.
Exercice 7 : synthèse – gestion d’une association sportive
Une association sportive gère ses adhérents et les activités proposées. Voici le schéma relationnel :
- Adherents(id_adh, nom, prenom, annee_naissance)
- Activites(id_act, nom_activite, jour, creneau, places_max)
- Inscriptions(id_insc, #id_adh, #id_act, date_inscription)
On dispose des données suivantes.
Adherents :
| id_adh | nom | prenom | annee_naissance |
|---|---|---|---|
| 1 | Dupont | Marie | 2007 |
| 2 | Martin | Lucas | 2006 |
| 3 | Leroy | Emma | 2008 |
| 4 | Petit | Hugo | 2007 |
| 5 | Bernard | Léa | 2006 |
Activites :
| id_act | nom_activite | jour | creneau | places_max |
|---|---|---|---|---|
| 10 | Natation | Mercredi | 14h-16h | 20 |
| 20 | Badminton | Samedi | 10h-12h | 15 |
| 30 | Escalade | Mercredi | 16h-18h | 12 |
Inscriptions :
| id_insc | id_adh | id_act | date_inscription |
|---|---|---|---|
| 1 | 1 | 10 | 2025-09-01 |
| 2 | 1 | 20 | 2025-09-01 |
| 3 | 2 | 10 | 2025-09-03 |
| 4 | 3 | 30 | 2025-09-05 |
| 5 | 4 | 10 | 2025-09-06 |
| 6 | 4 | 30 | 2025-09-06 |
| 7 | 5 | 20 | 2025-09-10 |
a) Écrivez une requête affichant les noms et prénoms des adhérents nés en 2007, triés par nom.
Indice
WHERE annee_naissance = 2007, puis ORDER BY nom.
b) Combien d’inscriptions ont été enregistrées en tout ? Écrivez la requête.
Indice
COUNT(*) sur la table Inscriptions.
c) Écrivez une requête affichant le nom et le prénom de chaque adhérent inscrit à « Natation ».
Indice
Deux jointures relient les trois tables : Adherents et Inscriptions par id_adh, puis Inscriptions et Activites par id_act. La condition porte sur nom_activite.
Code à copier puis compléter
SELECT Adherents.nom, Adherents.prenom
FROM Adherents
JOIN Inscriptions ON Adherents.id_adh = Inscriptions.id_adh
JOIN Activites ON ... = ...
WHERE Activites.nom_activite = ...;
d) Écrivez une requête affichant le nombre total d’inscrits à l’activité « Natation ».
Indice
Une jointure entre Inscriptions et Activites suffit, avec COUNT(*).
e) L’adhérent Hugo Petit souhaite se désinscrire de l’escalade. Écrivez la requête appropriée.
Indice
DELETE FROM Inscriptions WHERE ...; : repérer dans les tables l’id_adh de Hugo Petit et l’id_act de l’escalade.
f) Une nouvelle activité « Yoga » est proposée le vendredi de 17h à 18h30, avec 25 places. Attribuez-lui l’identifiant 40. Écrivez la requête d’insertion.
Indice
INSERT INTO Activites VALUES (...);, avec les cinq valeurs dans l’ordre des colonnes.
g) Léa Bernard souhaite s’inscrire à l’escalade (id_insc = 8, date : 2025-10-01). Écrivez la requête. La contrainte d’intégrité référentielle est-elle respectée ? Justifiez.
Indice
Vérifier que l’adhérent et l’activité désignés par les deux clés étrangères existent bien.
h) Un adhérent peut-il s’inscrire à une activité qui n’existe pas (par exemple id_act = 99) ? Expliquez pourquoi en citant la contrainte.
Indice
Que dit la contrainte d’intégrité référentielle de la valeur d’une clé étrangère ?
Correction publiée après la séance.