Retour à la page d'accueilNSI · Terminale (maths expertes) · Changer de matière
Commencer gratuitement
Terminale (maths expertes) · NSI
Préparer l'épreuve de spécialité NSI du bac · Épreuve de spécialité NSI du baccalauréat

Bases de données relationnelles et SQL

Un site de billetterie affiche « Il reste 1 place » pour un concert à Lyon. Deux personnes cliquent sur « Réserver » en même temps. Qui obtient la place ? Pour que les données restent cohérentes, il faut les organiser avec méthode et les confier à un logiciel spécialisé. C'est l'objet de ce chapitre, qui est un classique de l'épreuve de spécialité NSI du bac.

Le modèle relationnel

Dans une base de données relationnelle, les données sont rangées dans des relations, que l'on représente par des tableaux.

Exemple de relation :

num nom prenom classe
1 Martin Léa TG1
2 Bernard Hugo TG2

Son schéma s'écrit : ELEVE(num, nom, prenom, classe). Elle a 4 attributs. Avec les deux lignes ci-dessus, elle compte 2 enregistrements.

On distingue la structure de la base (le schéma, les domaines) de son contenu (les enregistrements, qui changent au cours du temps).

Le système de gestion de bases de données (SGBD) refuse un enregistrement dont la clef primaire existe déjà : c'est la contrainte d'unicité. Il refuse aussi une clef étrangère qui ne référence aucun enregistrement existant : c'est la contrainte d'intégrité référentielle.

Entraîne-toi★☆☆Pas commencé
Un lycée gère ses élèves avec la relation ELEVE, dont la clef primaire est num. | num | nom | prenom | classe | |---|---|---|---| | 1 | Martin | Léa | TG1 | | 2 |…

Un lycée gère ses élèves avec la relation ELEVE, dont la clef primaire est num.

num nom prenom classe
1 Martin Léa TG1
2 Bernard Hugo TG2
3 Petit Inès TG1
4 Moreau Tom TG3
  1. Donner le nombre d'attributs et le nombre d'enregistrements de cette relation, puis écrire son schéma relationnel.

  2. Indiquer un domaine possible pour l'attribut num et un domaine possible pour l'attribut classe.

  3. On exécute la requête suivante.

INSERT INTO ELEVE VALUES (3, 'Roux', 'Paul', 'TG2');
Expliquer pourquoi le système de gestion de bases de données refuse cette insertion.
  1. Écrire une requête SQL qui renvoie les noms des élèves de la classe TG1, puis donner son résultat.
Résoudre

Redondance et anomalies

Regardons une boutique qui range tout dans une seule relation :

num_cmd client adresse_client produit prix
101 Martin 12 rue Pasteur Cahier 2,50
102 Martin 12 rue Pasteur Stylo 1,20

L'adresse de Martin est écrite deux fois : c'est une redondance. Elle provoque des anomalies :

  • Mise à jour : si Martin déménage, il faut modifier toutes ses lignes ; en oublier une rend la base incohérente.

  • Insertion : on ne peut pas enregistrer un client qui n'a pas encore commandé, car il n'y a pas de numéro de commande.

  • Suppression : en supprimant la seule commande d'un client, on perd aussi son adresse.

La solution est de répartir les données en plusieurs relations reliées par des clefs étrangères : CLIENT(id_client, nom, adresse) et COMMANDE(num_cmd, id_client, produit, prix). Chaque information n'est alors écrite qu'une seule fois.

Entraîne-toi★★☆Pas commencé
Une boutique en ligne stocke ses commandes dans une unique relation. COMMANDE(num_cmd, client, adresse_client, produit, prix) | num_cmd | client | adresse_client |…

Une boutique en ligne stocke ses commandes dans une unique relation.

COMMANDE(num_cmd, client, adresse_client, produit, prix)

num_cmd client adresse_client produit prix
101 Martin 12 rue Pasteur Cahier 2,50
102 Martin 12 rue Pasteur Stylo 1,20
103 Leroy 5 avenue Foch Cahier 2,50
  1. Repérer les redondances présentes dans cette relation.

  2. Pour chacune des situations suivantes, décrire l'anomalie rencontrée.

    a) Mise à jour : le client Martin déménage.

    b) Insertion : on souhaite enregistrer un nouveau client qui n'a encore passé aucune commande.

    c) Suppression : on supprime la commande 103.

  3. Proposer un schéma relationnel à trois relations, CLIENT, PRODUIT et COMMANDE, qui supprime ces anomalies. Souligner les clefs primaires et indiquer les clefs étrangères.

  4. Indiquer, dans le nouveau schéma, ce que devient la mise à jour de l'adresse de Martin.

Résoudre

Interroger avec SQL

SQL est le langage d'interrogation des bases relationnelles. Une requête de sélection a cette forme :

SELECT attributs

FROM relation

WHERE condition

ORDER BY attribut;
  • SELECT choisit les colonnes, * signifie « toutes ».

  • FROM indique la relation.

  • WHERE filtre les lignes (=, <, >=, <>, AND, OR).

  • ORDER BY trie (par défaut croissant, DESC pour décroissant).

  • DISTINCT supprime les doublons.

  • Les fonctions d'agrégation COUNT, SUM, AVG, MIN, MAX calculent une valeur sur l'ensemble des lignes sélectionnées.

Les chaînes de caractères s'écrivent entre apostrophes : 'Dubois'. Au programme, il n'y a ni GROUP BY ni HAVING.

Entraîne-toi★☆☆Pas commencé
Un cinéma de quartier gère la relation FILM. | id | titre | realisateur | annee | duree | |---|---|---|---|---| | 1 | Le Phare | Dubois | 2015 | 95 | | 2 | Rue des Lilas…

Un cinéma de quartier gère la relation FILM.

id titre realisateur annee duree
1 Le Phare Dubois 2015 95
2 Rue des Lilas Lemaire 2018 110
3 Nuit blanche Dubois 2020 88
4 Le Grand Marché Garnier 2018 102
5 Terres rouges Lemaire 2021 125

La durée est exprimée en minutes. Donner le résultat de chacune des requêtes suivantes.

  1. SELECT titre FROM FILM WHERE annee = 2018;

  2. SELECT titre, duree FROM FILM WHERE realisateur = 'Dubois' ORDER BY duree;

  3. SELECT COUNT(*) FROM FILM WHERE annee >= 2018;

  4. SELECT AVG(duree) FROM FILM;

  5. Écrire une requête qui renvoie les titres des films dont la durée est strictement supérieure à 100 minutes, puis donner son résultat.

Résoudre

Joindre plusieurs relations

Pour afficher le nom d'un adhérent avec le titre du livre emprunté, il faut croiser plusieurs relations grâce aux clefs étrangères : c'est la jointure.

SELECT ADHERENT.nom, LIVRE.titre

FROM EMPRUNT

JOIN ADHERENT ON EMPRUNT.id_adh = ADHERENT.id_adh

JOIN LIVRE ON EMPRUNT.id_livre = LIVRE.id_livre

WHERE ADHERENT.ville = 'Lyon';

JOIN … ON … associe chaque ligne de EMPRUNT à la ligne de l'autre relation qui a la même valeur de clef. On préfixe les attributs par le nom de la relation (ADHERENT.nom) pour éviter toute ambiguïté.

Pour trouver les livres non rendus, on teste la valeur NULL avec IS NULL (jamais avec = NULL) : WHERE date_retour IS NULL.

Entraîne-toi★★☆Pas commencé
Une médiathèque utilise une base de données composée de trois relations. LIVRE(id_livre, titre, auteur) | id_livre | titre | auteur | |---|---|---| | 1 | Les Misérables…

Une médiathèque utilise une base de données composée de trois relations.

LIVRE(id_livre, titre, auteur)

id_livre titre auteur
1 Les Misérables Hugo
2 Germinal Zola
3 Candide Voltaire
4 Bel-Ami Maupassant

ADHERENT(id_adh, nom, ville)

id_adh nom ville
1 Dupont Lyon
2 Leroy Nantes
3 Fabre Lyon

EMPRUNT(id_adh, id_livre, date_emprunt)

id_adh id_livre date_emprunt
1 2 2025-03-04
1 3 2025-03-10
2 2 2025-03-12
3 1 2025-03-15
3 2 2025-03-20
  1. Identifier les clefs étrangères de la relation EMPRUNT et les relations auxquelles elles font référence.

  2. Écrire une requête qui renvoie les noms des adhérents ayant emprunté le livre « Germinal », puis donner son résultat trié par ordre alphabétique.

  3. Écrire une requête qui renvoie, sans doublon et par ordre alphabétique, les titres des livres empruntés par des adhérents habitant Lyon, puis donner son résultat.

  4. Donner le nombre de lignes renvoyées par la requête de la question 3 si l'on supprime le mot-clef DISTINCT.

  5. Écrire une requête qui renvoie le nombre total d'emprunts, puis donner son résultat.

Résoudre
Entraîne-toi★★☆Pas commencé
Un lycée stocke les notes de ses élèves dans deux relations. ELEVE(id, nom, classe) | id | nom | classe | |---|---|---| | 1 | Martin | TG1 | | 2 | Petit | TG1 | | 3 |…

Un lycée stocke les notes de ses élèves dans deux relations.

ELEVE(id, nom, classe)

id nom classe
1 Martin TG1
2 Petit TG1
3 Moreau TG2

NOTE(id_eleve, matiere, valeur)

id_eleve matiere valeur
1 NSI 15
1 Maths 12
2 NSI 11
2 Maths 14
3 NSI 17
3 Maths 9

Pour chacune des questions suivantes, écrire la requête SQL demandée, puis donner son résultat.

  1. Calculer la moyenne des notes de NSI de l'ensemble des élèves. Arrondir au centième.

  2. Donner le nom et la note de NSI des élèves de la classe TG1, par ordre décroissant de note.

  3. Déterminer le nombre de notes strictement supérieures à 12.

  4. Déterminer la meilleure note de mathématiques.

  5. Calculer la moyenne des notes de NSI des élèves de la classe TG1.

Résoudre
Entraîne-toi★★★Pas commencé
Une médiathèque gère ses prêts avec les relations suivantes. L'attribut date_retour vaut NULL tant que le livre n'a pas été rendu, et le test se fait avec IS NULL.…

Une médiathèque gère ses prêts avec les relations suivantes. L'attribut date_retour vaut NULL tant que le livre n'a pas été rendu, et le test se fait avec IS NULL.

LIVRE(id_livre, titre, auteur)

id_livre titre auteur
1 Les Misérables Hugo
2 Germinal Zola
3 Candide Voltaire

ADHERENT(id_adh, nom, ville)

id_adh nom ville
1 Dupont Lyon
2 Leroy Nantes
3 Fabre Lyon

EMPRUNT(id_adh, id_livre, date_emprunt, date_retour)

id_adh id_livre date_emprunt date_retour
1 2 2025-03-04 2025-03-18
1 3 2025-03-10 NULL
2 2 2025-03-12 NULL
3 1 2025-03-15 2025-03-29
3 2 2025-03-20 NULL
  1. Écrire une requête qui renvoie le nom de l'adhérent et le titre du livre pour chaque emprunt non rendu, puis donner son résultat trié par nom.

  2. Écrire une requête qui renvoie, sans doublon, les noms des adhérents ayant emprunté au moins un livre de Zola, puis donner son résultat trié par ordre alphabétique.

  3. Écrire une requête qui enregistre le retour du livre 2 par l'adhérent 2 le 2025-04-01, puis donner le nombre d'emprunts non rendus après cette mise à jour.

  4. On exécute INSERT INTO EMPRUNT VALUES (4, 1, '2025-04-02', NULL);. Expliquer pourquoi un système de gestion de bases de données qui vérifie l'intégrité référentielle refuse cette insertion.

Résoudre
Entraîne-toi★★★Pas commencé
Un réseau régional de trains TER est décrit par deux relations. L'attribut duree_min est la durée du trajet en minutes. Les attributs gare_depart et gare_arrivee sont…

Un réseau régional de trains TER est décrit par deux relations. L'attribut duree_min est la durée du trajet en minutes. Les attributs gare_depart et gare_arrivee sont des clefs étrangères qui référencent GARE.

GARE(id_gare, nom, ville)

id_gare nom ville
1 Dijon-Ville Dijon
2 Beaune Beaune
3 Chalon-sur-Saône Chalon
4 Mâcon-Ville Mâcon

TRAJET(id_trajet, gare_depart, gare_arrivee, duree_min)

id_trajet gare_depart gare_arrivee duree_min
1 1 2 25
2 2 3 20
3 3 4 35
4 1 3 40
5 1 4 70
  1. Expliquer pourquoi la relation GARE doit être utilisée deux fois dans une requête qui affiche le nom de la gare de départ et le nom de la gare d'arrivée de chaque trajet.

  2. Écrire une requête qui renvoie, pour chaque trajet dont la durée est strictement inférieure à 40 minutes, le nom de la gare de départ, le nom de la gare d'arrivée et la durée. On utilisera deux alias de la relation GARE. Donner le résultat par ordre croissant de durée.

  3. Donner le résultat de SELECT SUM(duree_min) FROM TRAJET WHERE id_trajet <= 3;.

  4. Les trajets 1, 2 et 3 forment un itinéraire de Dijon-Ville à Mâcon-Ville avec arrêts. Comparer sa durée totale à celle du trajet direct 5.

  5. Écrire une requête qui supprime le trajet 4, puis donner le nombre de lignes de la relation TRAJET après cette suppression.

Résoudre

Modifier les données

Trois requêtes modifient le contenu de la base :

INSERT INTO PRODUIT VALUES (4, 'Règle', 0.90, 60);

UPDATE PRODUIT SET prix = 1.50 WHERE nom = 'Stylo';

DELETE FROM PRODUIT WHERE stock < 30;
  • INSERT INTO ajoute un enregistrement (les valeurs suivent l'ordre des attributs).

  • UPDATE … SET … WHERE modifie des valeurs existantes.

  • DELETE FROM … WHERE supprime des lignes.

En SQL, le séparateur décimal est le point (0.90) et non la virgule, contrairement à l'écriture française habituelle (0,90).

Pour augmenter un stock, on peut utiliser l'ancienne valeur : UPDATE PRODUIT SET stock = stock + 10 WHERE ref = 1;.

Entraîne-toi★☆☆Pas commencé
Une papeterie utilise la relation PRODUIT suivante (prix en euros). | ref | nom | prix | stock | |---|---|---|---| | 1 | Cahier | 2,50 | 40 | | 2 | Stylo | 1,20 | 100 |…

Une papeterie utilise la relation PRODUIT suivante (prix en euros).

ref nom prix stock
1 Cahier 2,50 40
2 Stylo 1,20 100
3 Classeur 4,80 25

On exécute successivement les trois requêtes suivantes.

UPDATE PRODUIT SET prix = 1.50 WHERE nom = 'Stylo';

DELETE FROM PRODUIT WHERE stock < 30;

INSERT INTO PRODUIT VALUES (4, 'Règle', 0.90, 60);
  1. Donner le contenu de la relation PRODUIT après chacune de ces requêtes.

  2. Écrire une requête qui augmente de 10 unités le stock du produit de référence 1.

  3. Indiquer, parmi UPDATE, DELETE, INSERT et SELECT, celles qui modifient le contenu de la base.

Résoudre

Les services d'un SGBD

Un SGBD n'est pas qu'un simple fichier : il rend quatre services principaux (sans qu'on ait à connaître son fonctionnement interne).

  • Persistance : les données restent enregistrées après l'arrêt du programme.

  • Gestion des accès concurrents : plusieurs utilisateurs peuvent lire et écrire en même temps sans corrompre les données.

  • Efficacité du traitement des requêtes : même sur de très gros volumes.

  • Sécurisation des accès : chaque utilisateur n'a que les droits qui lui sont accordés.

Entraîne-toi★★★Pas commencé
Un site de réservation de places de concert enregistre ses données dans un système de gestion de bases de données. La relation PLACE contient notamment une ligne dont…

Un site de réservation de places de concert enregistre ses données dans un système de gestion de bases de données. La relation PLACE contient notamment une ligne dont l'attribut stock vaut 1 pour la référence 7.

Deux clients, Alice et Bob, cherchent à réserver cette dernière place au même moment. Le programme de chacun exécute les trois étapes suivantes.

  1. Lire la valeur de stock pour la référence 7.

  2. Si cette valeur est supérieure à 0, calculer stock - 1.

  3. Écrire la nouvelle valeur dans la base.

Les opérations s'entrelacent ainsi : Alice exécute l'étape 1, Bob exécute l'étape 1, Alice exécute les étapes 2 et 3, puis Bob exécute les étapes 2 et 3.

  1. Donner la valeur de stock à la fin de l'exécution et le nombre de places réellement vendues. Expliquer le problème rencontré.

  2. Citer le service d'un système de gestion de bases de données qui a pour rôle d'éviter ce problème.

  3. On propose la requête unique suivante.

UPDATE PLACE SET stock = stock - 1 WHERE ref = 7 AND stock > 0;
Expliquer pourquoi son exécution par un système de gestion de bases de données qui garantit l'absence d'accès concurrents conflictuels résout le problème.
  1. La relation CLIENT du site contient les attributs nom, prenom, email, date_naissance, adresse, numero_securite_sociale et historique_navigation. Le seul usage prévu est l'envoi des billets par courriel.

    a) Indiquer les attributs qui ne sont pas nécessaires à cet usage.

    b) Justifier ce choix par un principe de minimisation des données personnelles prévu par le RGPD.

Résoudre

L'essentiel

  • Une base relationnelle est un ensemble de relations (tableaux). Chaque relation a des attributs (colonnes) avec un domaine, et des enregistrements (lignes).

  • La clef primaire identifie un enregistrement. La clef étrangère référence la clef primaire d'une autre relation.

  • La redondance cause des anomalies de mise à jour, d'insertion et de suppression. On l'évite en séparant les données en plusieurs relations.

  • SELECT … FROM … WHERE … ORDER BY, avec DISTINCT, COUNT, SUM, AVG, MIN, MAX et JOIN … ON ….

  • INSERT, UPDATE et DELETE modifient le contenu. Toujours soigner le WHERE.

  • Un SGBD assure la persistance, la gestion des accès concurrents, l'efficacité des requêtes et la sécurisation des accès.

Retour au début : la dernière place de concert est attribuée à une seule personne parce que le SGBD gère les accès concurrents par des transactions.

Voir tous les exercices de cette partie