Retour à la page d'accueilNSI · Terminale (maths complémentaires) · Changer de matière
Commencer gratuitement
Terminale (maths complémentaires) · NSI
Structures de données, bases de données et algorithmique · Bases de données relationnelles

Modèle relationnel et langage SQL

La médiathèque de Nantes gère ses adhérents et ses prêts. Si elle note dans un seul grand tableau le nom, l'adresse et la ville de chaque adhérent à chaque emprunt, que se passe-t-il quand Léa déménage ? Il faut corriger des dizaines de lignes, et on risque d'en oublier une. Les bases de données relationnelles ont été inventées pour éviter ce genre de problème. À la fin de cette page, tu sauras les organiser et les interroger.

Tables, attributs et clefs

Une base de données relationnelle range l'information dans des relations, que l'on représente par des tables. Chaque ligne décrit un objet (un élève, un livre…), chaque colonne décrit une de ses caractéristiques.

Exemple de schéma, la clef primaire étant soulignée en pratique, ici écrite en premier : Adherent(num, nom, ville) et Emprunt(id, num_adherent, titre, date_emprunt).

Deux tables, Adherent et Emprunt, reliées par la clef étrangère num_adherent qui référence la clef primaire num Adherent num (clef primaire) nom ville Emprunt id (clef primaire) num_adherent (clef étrangère) titre date_emprunt référence

La clef étrangère garantit la cohérence : on ne peut pas enregistrer un emprunt pour un numéro d'adhérent qui n'existe pas. C'est le SGBD (système de gestion de bases de données) qui le vérifie. Il assure aussi la persistance des données, la gestion des accès simultanés, l'efficacité des requêtes et la sécurisation des accès.

Entraîne-toi★☆☆Pas commencé
Une relation Eleve(id, nom, prenom, classe) a pour clef primaire id. a) Expliquer ce qu'est une relation, un attribut et un domaine, en prenant des exemples dans Eleve.…

Une relation Eleve(id, nom, prenom, classe) a pour clef primaire id.

  1. a) Expliquer ce qu'est une relation, un attribut et un domaine, en prenant des exemples dans Eleve.
  1. b) Expliquer le rôle d'une clef primaire et pourquoi deux élèves ne peuvent pas avoir le même id.
  1. c) Donner le schéma de la relation.
Résoudre

Interroger : SELECT, FROM, WHERE

SQL est un langage déclaratif : on décrit ce qu'on veut obtenir, pas comment le calculer. Une requête de sélection a la forme :

SELECT attributs

FROM table

WHERE condition

ORDER BY attribut;

Prenons Livre(id, titre, auteur, annee, prix) :

id titre auteur annee prix
1 Germinal Zola 1885 7,50
2 Candide Voltaire 1759 5,00
3 Nana Zola 1880 8,00

(Dans les exemples de cette page, on écrit les nombres décimaux avec la virgule, comme en français : 7,50.)

Quelques outils utiles :

  • Comparaisons : =, <>, <, <=, >, >= ; connecteurs AND, OR, NOT.

  • ORDER BY prix trie par prix croissant ; ORDER BY prix DESC par prix décroissant.

  • DISTINCT supprime les doublons : SELECT DISTINCT auteur FROM Livre;

  • LIMIT 3 ne garde que les trois premières lignes du résultat.

  • SELECT * renvoie toutes les colonnes.

Entraîne-toi★☆☆Pas commencé
On considère la table Livre(id, titre, auteur, annee, prix) contenant, entre autres, les livres suivants : (1, "Germinal", "Zola", 1885, 7.50), (2, "Candide",…

On considère la table Livre(id, titre, auteur, annee, prix) contenant, entre autres, les livres suivants : (1, "Germinal", "Zola", 1885, 7.50), (2, "Candide", "Voltaire", 1759, 5.00), (3, "Nana", "Zola", 1880, 8.00).

  1. a) Écrire la requête SQL qui renvoie les titres des livres de Zola.
  1. b) Écrire la requête qui renvoie tous les livres triés par prix croissant.
  1. c) Donner le résultat de la requête SELECT titre FROM Livre WHERE annee < 1882;.
Résoudre

Modifier : INSERT, UPDATE, DELETE

Les requêtes de mise à jour changent le contenu de la base.

INSERT INTO Livre (id, titre, auteur, annee, prix)

VALUES (5, 'Bel-Ami', 'Maupassant', 1885, 6.50);

UPDATE Livre SET prix = 5.50 WHERE id = 2;



DELETE FROM Livre WHERE annee < 1700;
Entraîne-toi★☆☆Pas commencé
Avec la table Livre(id, titre, auteur, annee, prix) de l'exercice précédent : a) Écrire la requête qui ajoute le livre (4, "Au bonheur des dames", "Zola", 1883, 9.00).…

Avec la table Livre(id, titre, auteur, annee, prix) de l'exercice précédent :

  1. a) Écrire la requête qui ajoute le livre (4, "Au bonheur des dames", "Zola", 1883, 9.00).
  1. b) Écrire la requête qui passe le prix du livre d'id 2 à 6,00.
  1. c) Écrire la requête qui supprime les livres publiés avant 1800.
Résoudre

Agréger et regrouper

Pour faire des calculs sur plusieurs lignes, on utilise des fonctions d'agrégation : COUNT(*) (nombre de lignes), SUM(x) (somme), AVG(x) (moyenne), MIN(x), MAX(x). Elles renvoient une seule valeur.

Table Vente(id, produit, magasin, quantite, prix_unitaire) :

id produit magasin quantite prix_unitaire
1 baguette Lyon 40 1,10
2 croissant Lyon 25 1,20
3 baguette Lille 30 1,10

SELECT SUM(quantite) FROM Vente; renvoie 95. On peut aussi calculer sur une expression : SUM(quantite * prix_unitaire).

GROUP BY forme des groupes de lignes qui ont la même valeur, et l'agrégation s'applique à chaque groupe.

WHERE filtre les lignes avant le regroupement. HAVING filtre les groupes après, donc c'est le seul à pouvoir porter sur un résultat d'agrégation.

SELECT magasin, SUM(quantite)

FROM Vente

GROUP BY magasin

HAVING SUM(quantite) > 50;

Cette requête ne renvoie que Lyon. Écrire WHERE SUM(quantite) > 50 provoquerait une erreur : à ce stade, les sommes ne sont pas encore calculées.

Pour obtenir les plus grandes valeurs, on trie en ordre décroissant puis on limite : ORDER BY quantite DESC LIMIT 3.

Entraîne-toi★★☆Pas commencé
La table Vente(id, produit, magasin, quantite, prix_unitaire) recense les ventes d'une chaîne de boulangeries. a) Écrire la requête qui calcule le chiffre d'affaires…

La table Vente(id, produit, magasin, quantite, prix_unitaire) recense les ventes d'une chaîne de boulangeries.

  1. a) Écrire la requête qui calcule le chiffre d'affaires total ($\text{quantité} \times \text{prix unitaire}$).
  1. b) Écrire la requête qui donne, pour chaque magasin, la quantité totale vendue.
  1. c) Écrire la requête qui renvoie le prix unitaire moyen des ventes du produit « baguette ».
  1. d) Écrire la requête qui renvoie les trois ventes de plus grande quantité.
Résoudre

Relier les tables : les jointures

Les informations sont réparties dans plusieurs tables ; une jointure les recombine en suivant les clefs étrangères.

SELECT Adherent.nom, Emprunt.titre

FROM Adherent

JOIN Emprunt ON Adherent.num = Emprunt.num_adherent;

JOIN … ON … associe chaque ligne de Adherent aux lignes de Emprunt pour lesquelles la condition est vraie. On préfixe les attributs par le nom de la table (Adherent.nom) pour lever toute ambiguïté.

On peut combiner jointure, WHERE, AVG, HAVING… en suivant toujours le même ordre d'écriture : SELECT, FROM, JOIN, WHERE, GROUP BY, HAVING, ORDER BY.

Pour trouver les éléments sans correspondance (par exemple les adhérents qui n'ont rien emprunté), une jointure ne suffit pas, car elle ne garde que les lignes appariées. On utilise une sous-requête avec NOT IN :

SELECT nom FROM Adherent

WHERE num NOT IN (SELECT num_adherent FROM Emprunt);
Entraîne-toi★★☆Pas commencé
Une médiathèque de Nantes utilise les tables Adherent(num, nom, ville) et Emprunt(id, num_adherent, titre, date_emprunt), où num_adherent est une clef étrangère vers…

Une médiathèque de Nantes utilise les tables Adherent(num, nom, ville) et Emprunt(id, num_adherent, titre, date_emprunt), où num_adherent est une clef étrangère vers Adherent(num).

  1. a) Expliquer le rôle de la clef étrangère.
  1. b) Écrire la requête qui renvoie le nom des adhérents et les titres qu'ils ont empruntés.
  1. c) Écrire la requête qui renvoie le nombre d'emprunts de chaque adhérent (numéro et nombre).
  1. d) Écrire la requête qui renvoie sans doublon les villes des adhérents ayant emprunté au moins un livre.
Résoudre
Entraîne-toi★★★Pas commencé
Un lycée gère les relations Eleve(id, nom, classe), Matiere(code, intitule) et Note(id_eleve, code_matiere, valeur). La clef primaire de Note est le couple (id_eleve,…

Un lycée gère les relations Eleve(id, nom, classe), Matiere(code, intitule) et Note(id_eleve, code_matiere, valeur). La clef primaire de Note est le couple (id_eleve, code_matiere).

  1. a) Donner les clefs étrangères du schéma.
  1. b) Écrire la requête qui renvoie, pour chaque élève (nom), sa moyenne en « Mathématiques ».
  1. c) Écrire la requête qui renvoie les noms des élèves de classe « T1 » dont la moyenne en « NSI » dépasse 14.
  1. d) Expliquer pourquoi l'insertion d'une note avec un id_eleve inexistant doit être refusée et par quel mécanisme.
Résoudre
Entraîne-toi★★★Pas commencé
Soit la table Film(id, titre, realisateur, annee) et la table Projection(id_film, salle, heure) où id_film est une clef étrangère. a) Écrire la requête qui renvoie les…

Soit la table Film(id, titre, realisateur, annee) et la table Projection(id_film, salle, heure) où id_film est une clef étrangère.

  1. a) Écrire la requête qui renvoie les titres des films projetés dans au moins deux salles différentes.
  1. b) Écrire la requête qui renvoie les réalisateurs dont aucun film n'est projeté.
  1. c) Expliquer la différence entre WHERE et HAVING en justifiant l'usage nécessaire de l'un d'eux dans la question a).
Résoudre

Bien concevoir : redondance et anomalies

Reprenons notre médiathèque, avec une seule table :

num_pret nom ville titre
1 Léa Nantes Germinal
2 Léa Nantes Nana
3 Hugo Rezé Candide

La ville de Léa est écrite deux fois : c'est de la redondance. Elle provoque trois anomalies :

  • mise à jour : si Léa déménage, il faut modifier toutes ses lignes, sinon la base devient incohérente ;

  • insertion : on ne peut pas enregistrer un nouvel adhérent qui n'a encore rien emprunté ;

  • suppression : si on supprime le seul prêt de Hugo, on perd aussi les informations sur Hugo.

Remède : séparer les informations en relations, chacune décrivant un seul type d'objet, reliées par des clefs étrangères :

  • Adherent(num, nom, ville), clef primaire num ;

  • Livre(code, titre), clef primaire code ;

  • Pret(num_pret, num_adherent, code_livre), clef primaire num_pret, clefs étrangères num_adherent → Adherent(num) et code_livre → Livre(code).

Chaque information n'est plus écrite qu'une seule fois. Les tables se créent avec CREATE TABLE :

CREATE TABLE Adherent (

    num INTEGER PRIMARY KEY,

    nom TEXT,

    ville TEXT

);

CREATE TABLE Pret (

    num_pret INTEGER PRIMARY KEY,

    num_adherent INTEGER,

    code_livre INTEGER,

    FOREIGN KEY (num_adherent) REFERENCES Adherent(num),

    FOREIGN KEY (code_livre) REFERENCES Livre(code)

);

Quand la clef primaire est formée de deux attributs, on l'écrit PRIMARY KEY (a, b). Le SGBD refuse alors toute insertion qui ferait doublon sur le couple, ou qui référencerait une clef inexistante : c'est la contrainte d'intégrité référentielle.

Entraîne-toi★★☆Pas commencé
Voici une table unique Commande(num, client, adresse_client, produit, prix) : (1, "Durand", "12 rue Verte, Rennes", "stylo", 2,00) (2, "Durand", "12 rue Verte, Rennes",…

Voici une table unique Commande(num, client, adresse_client, produit, prix) :

(1, "Durand", "12 rue Verte, Rennes", "stylo", 2,00)

(2, "Durand", "12 rue Verte, Rennes", "cahier", 3,50)

(3, "Morel", "5 av. Foch, Brest", "stylo", 2,00)

  1. a) Repérer la redondance présente dans cette table.
  1. b) Décrire une anomalie de mise à jour, une anomalie d'insertion et une anomalie de suppression.
  1. c) Proposer un schéma à trois relations, avec clefs primaires et étrangères, qui supprime ces anomalies.
Résoudre
Entraîne-toi★★★Pas commencé
On considère la relation Inscription(num_etudiant, nom_etudiant, code_cours, intitule_cours, enseignant), avec la clef primaire (num_etudiant, code_cours). Un cours a un…

On considère la relation Inscription(num_etudiant, nom_etudiant, code_cours, intitule_cours, enseignant), avec la clef primaire (num_etudiant, code_cours). Un cours a un seul intitulé et un seul enseignant.

  1. a) Montrer que cette relation présente des redondances et des anomalies d'insertion, de suppression et de mise à jour.
  1. b) Proposer une décomposition en relations sans redondance, en précisant clefs primaires et étrangères.
  1. c) Écrire en SQL les instructions CREATE TABLE correspondantes.
  1. d) Écrire la requête qui reconstitue la liste (nom d'étudiant, intitulé du cours, enseignant).
Résoudre

Retour à notre médiathèque : quand Léa déménage, il suffit maintenant de modifier une seule ligne de Adherent, et tous ses prêts restent cohérents.

L'essentiel

  • Une base relationnelle est un ensemble de relations (tables) ; leurs colonnes sont les attributs, chacun avec son domaine.

  • La clef primaire identifie chaque enregistrement ; une clef étrangère référence la clef primaire d'une autre table et garantit la cohérence.

  • Requête de sélection : SELECT … FROM … WHERE … ORDER BY … ; DISTINCT supprime les doublons.

  • Mise à jour : INSERT INTO, UPDATE … SET … WHERE, DELETE FROM … WHERE (ne jamais oublier le WHERE).

  • Agrégation : COUNT, SUM, AVG, MIN, MAX ; avec GROUP BY (hors programme) on calcule par groupe, et HAVING filtre les groupes.

  • Jointure : JOIN … ON clef_étrangère = clef_primaire.

  • Une table qui répète des informations provoque des anomalies de mise à jour, d'insertion et de suppression : on décompose en plusieurs relations reliées par des clefs.

Voir tous les exercices de cette partie