🗄️

S02 — Bases de données

Modèle relationnel, SQL, jointures, normalisation

SQL Relationnel ACID

🎯 Introduction

Une base de données relationnelle organise les données en tables (relations) composées de lignes (tuples) et de colonnes (attributs). SQL est le langage de requête standard.

✅ Ce qu'il faut savoir

  • Modèle relationnel : table, attribut, tuple, schéma
  • Clé primaire (PK), clé étrangère (FK), contrainte d'intégrité référentielle
  • SELECT, FROM, WHERE, ORDER BY, LIMIT
  • Fonctions d'agrégat : COUNT, SUM, AVG, MIN, MAX avec GROUP BY et HAVING
  • Jointures : JOIN (INNER), LEFT JOIN
  • INSERT, UPDATE, DELETE

📐 Modèle relationnel

Exemple : une base de données de bibliothèque.

-- Schéma relationnel
CREATE TABLE Auteur (
    id_auteur   INTEGER  PRIMARY KEY,
    nom         TEXT     NOT NULL,
    nationalite TEXT
);

CREATE TABLE Livre (
    isbn        TEXT     PRIMARY KEY,
    titre       TEXT     NOT NULL,
    annee       INTEGER,
    id_auteur   INTEGER  REFERENCES Auteur(id_auteur)
                          ON DELETE CASCADE
);
TermeDéfinition
Clé primaire (PK)Attribut(s) qui identifient uniquement chaque ligne
Clé étrangère (FK)Attribut qui référence la clé primaire d'une autre table
CardinalitéNombre de lignes satisfaisant une condition (lié à COUNT)
DomaineEnsemble des valeurs possibles d'un attribut
Intégrité référentielleChaque FK doit référencer une PK existante

📝 SQL — Requêtes de base

-- Sélectionner toutes les colonnes
SELECT * FROM Livre;

-- Sélection avec condition
SELECT titre, annee
FROM Livre
WHERE annee > 2000
ORDER BY annee DESC;

-- Insérer des données
INSERT INTO Auteur (id_auteur, nom, nationalite)
VALUES (1, 'Camus', 'Française');

-- Modifier des données
UPDATE Livre SET annee = 1942
WHERE isbn = '978-X';

-- Supprimer des lignes
DELETE FROM Auteur
WHERE id_auteur = 5;

🔗 Jointures

💡

Principe de la jointure

Une jointure combine les lignes de deux tables selon une condition de correspondance. Le plus souvent : table1.fk = table2.pk.

-- INNER JOIN : seulement les lignes ayant une correspondance
SELECT Livre.titre, Auteur.nom
FROM Livre
JOIN Auteur ON Livre.id_auteur = Auteur.id_auteur;

-- LEFT JOIN : toutes les lignes de gauche + correspondances (NULL si absent)
SELECT Auteur.nom, Livre.titre
FROM Auteur
LEFT JOIN Livre ON Auteur.id_auteur = Livre.id_auteur;
-- → inclut les auteurs qui n'ont pas de livre (titre = NULL)

-- Jointure de 3 tables
SELECT E.nom, C.nom_cours, N.note
FROM Etudiant E
JOIN Note N ON E.id = N.id_etudiant
JOIN Cours C ON N.id_cours = C.id
WHERE N.note >= 10;

📊 Fonctions d'agrégat

-- COUNT, SUM, AVG, MIN, MAX
SELECT COUNT(*) AS nb_livres        -- nombre total
FROM Livre;

-- GROUP BY : grouper par auteur
SELECT id_auteur, COUNT(*) AS nb_livres
FROM Livre
GROUP BY id_auteur;

-- HAVING : filtrer les groupes (après GROUP BY)
SELECT id_auteur, COUNT(*) AS nb
FROM Livre
GROUP BY id_auteur
HAVING COUNT(*) >= 3;   -- auteurs avec 3+ livres

-- Requête combinée avec jointure
SELECT Auteur.nom, AVG(Note.note) AS moyenne
FROM Auteur
JOIN Livre ON Auteur.id = Livre.id_auteur
GROUP BY Auteur.nom
HAVING AVG(Note.note) > 4.0
ORDER BY moyenne DESC;
🚨

WHERE vs HAVING

WHERE filtre les lignes avant le GROUP BY. HAVING filtre les groupes après le GROUP BY. On ne peut pas utiliser une fonction agrégat dans le WHERE !

❌ WHERE COUNT(*) > 3 → erreur | ✅ HAVING COUNT(*) > 3

🔒 Contraintes et normalisation

ContrainteEffet
NOT NULLLa valeur ne peut pas être NULL
UNIQUEChaque valeur doit être unique dans la colonne
PRIMARY KEYNOT NULL + UNIQUE — identifiant unique
FOREIGN KEYRéférence à une PK d'une autre table
CHECKVérifie une condition booléenne
📐

Propriétés ACID

Atomicité : tout ou rien | Cohérence : intégrité préservée | Isolation : transactions indépendantes | Durabilité : données persistées

🚨

Pièges SQL au bac

  • COUNT(*) compte toutes les lignes, COUNT(col) ignore les NULL
  • Dans un SELECT avec GROUP BY, on ne peut mettre que des colonnes du GROUP BY ou des fonctions d'agrégat
  • La jointure INNER JOIN exclut les lignes sans correspondance (différent de LEFT JOIN)
  • SQL n'est pas sensible à la casse pour les mots clés (SELECT = select), mais peut l'être pour les données

🏋️ Exercices

FacileRequête de sélection

Table Eleve(id, nom, classe, note). Écrire une requête SQL pour obtenir les noms des élèves de la classe 'TG1' ayant une note supérieure à 15, triés par note décroissante.

✅ Correction
SELECT nom
FROM Eleve
WHERE classe = 'TG1' AND note > 15
ORDER BY note DESC;
Niveau bacJointure et agrégat

Tables : Client(id_client, nom, ville) et Commande(id_cmd, id_client, montant, date).
Trouver le nom et le montant total des commandes pour les clients de Paris ayant commandé pour plus de 500€ au total.

✅ Correction
SELECT C.nom, SUM(Cmd.montant) AS total
FROM Client C
JOIN Commande Cmd ON C.id_client = Cmd.id_client
WHERE C.ville = 'Paris'
GROUP BY C.nom
HAVING SUM(Cmd.montant) > 500;

On filtre d'abord les clients de Paris (WHERE), puis on groupe et on filtre les groupes (HAVING).

📌 Fiche synthèse

STRUCTURE SQL

  • SELECT ... FROM ...
  • WHERE (filtre lignes)
  • GROUP BY + HAVING
  • ORDER BY ... ASC/DESC

JOINTURES

  • JOIN = INNER JOIN (intersection)
  • LEFT JOIN (tout à gauche)
  • ON table1.fk = table2.pk
  • 3 tables = 2 JOIN

AGRÉGATS

  • COUNT(*) / COUNT(col)
  • SUM, AVG, MIN, MAX
  • WHERE ≠ HAVING
  • NULL ignoré par AVG, SUM

🧠 QCM

Choisissez le nombre de questions et le niveau, puis lancez.

← S01 — Structures de données Algorithmique →