Partie 18 — Bases de données : comprendre MySQL et SQL
À partir du moment où tu veux créer un site “vrai” (connexion, concours, articles, QCM, profils…), tu as besoin d’une base de données. Le fichier PHP peut afficher une page, mais la base de données, elle, permet de stocker, organiser, rechercher et mettre à jour tes informations.
MySQL est l’un des systèmes les plus utilisés. SQL, c’est le langage pour parler à la base : demander des données, les ajouter, les modifier, les supprimer.
👉 Objectif : comprendre la logique d’une base relationnelle, écrire des requêtes SQL propres (SELECT/INSERT/UPDATE/DELETE), comprendre les relations (JOIN), et apprendre les réflexes de performance et de sécurité.
1) C’est quoi une base de données relationnelle ?
Une base relationnelle organise les données en tables. Une table, c’est comme un tableau Excel :
- Colonnes = champs (id, nom, email…)
- Lignes = enregistrements (un utilisateur, un article…)
Exemple table users :
| id | name | created_at | |
|---|---|---|---|
| 1 | Amine | amine@test.com | 2026-02-10 10:00:00 |
| 2 | Salma | salma@test.com | 2026-02-10 12:30:00 |
Le “relationnel” vient du fait que les tables peuvent être liées : un utilisateur peut avoir plusieurs articles, un article peut avoir plusieurs commentaires, etc.
2) Les clés : Primary Key et Foreign Key (super important)
2.1 Clé primaire (Primary Key)
La clé primaire est l’identifiant unique d’une ligne.
Exemple : users.id (souvent auto-increment).
✅ Règle : chaque table sérieuse doit avoir une clé primaire.
2.2 Clé étrangère (Foreign Key)
Une clé étrangère relie une table à une autre.
Exemple : posts.user_id pointe vers users.id.
Donc : “ce post appartient à quel user ?” → via user_id.
3) SQL : CRUD (Create, Read, Update, Delete)
Les 4 actions de base sur une table :
- INSERT : créer
- SELECT : lire
- UPDATE : modifier
- DELETE : supprimer
3.1 INSERT (ajouter une ligne)
INSERT INTO users (name, email, created_at)
VALUES ("Amine", "amine@test.com", NOW());
3.2 SELECT (lire des données)
SELECT id, name, email FROM users;
3.3 UPDATE (modifier)
UPDATE users SET name = "Salma B." WHERE id = 2;
3.4 DELETE (supprimer)
DELETE FROM users WHERE id = 2;
⚠️ Sans WHERE, UPDATE/DELETE peut toucher toute la table. Toujours vérifier !
4) SELECT plus puissant : WHERE, ORDER BY, LIMIT
4.1 WHERE (filtrer)
SELECT * FROM users WHERE email = "amine@test.com";
4.2 ORDER BY (trier)
SELECT * FROM users ORDER BY id DESC;
4.3 LIMIT (limiter)
SELECT * FROM users ORDER BY id DESC LIMIT 10;
Cas réel : pagination (page 1, page 2, etc.). Tu verras ça en détail quand on reliera SQL à PHP (PDO).
5) LIKE, IN, BETWEEN : requêtes “recherche”
5.1 LIKE (recherche partielle)
SELECT * FROM users WHERE name LIKE "%am%";
% signifie “n’importe quoi”.
Exemple : “Amine”, “Samir”, “Hamada”… selon la casse et la collation.
5.2 IN (liste de valeurs)
SELECT * FROM users WHERE id IN (1, 5, 9);
5.3 BETWEEN (intervalle)
SELECT * FROM users WHERE created_at BETWEEN "2026-02-01 00:00:00" AND "2026-02-28 23:59:59";
6) Agrégations : COUNT, SUM, AVG, GROUP BY
Les agrégations servent à produire des statistiques. Exemple : combien d’utilisateurs ? combien de posts par user ?
6.1 COUNT (compter)
SELECT COUNT(*) AS total_users FROM users;
6.2 GROUP BY (regrouper)
Exemple : nombre de posts par user.
SELECT user_id, COUNT(*) AS total_posts FROM posts GROUP BY user_id ORDER BY total_posts DESC;
Cas réel : classement des utilisateurs les plus actifs, stats admin, dashboard.
7) JOIN : relier des tables (le vrai pouvoir du relationnel)
Les JOIN permettent de combiner des tables. Exemple : afficher les posts avec le nom de l’auteur.
7.1 INNER JOIN (ce qui existe des deux côtés)
SELECT posts.id, posts.title, users.name FROM posts INNER JOIN users ON users.id = posts.user_id;
INNER JOIN = on ne garde que les posts qui ont un user correspondant.
7.2 LEFT JOIN (garder tout à gauche)
Utile si tu veux garder les posts même si l’auteur a été supprimé (ou null).
SELECT posts.id, posts.title, users.name FROM posts LEFT JOIN users ON users.id = posts.user_id;
✅ Réflexe : choisis INNER JOIN si tu veux des données “propres”. Choisis LEFT JOIN si tu veux “tout” côté gauche, même si l’autre table manque.
8) Index : performance et vitesse des recherches
Un index, c’est comme un sommaire dans un livre : au lieu de parcourir toutes les pages, MySQL peut retrouver rapidement les lignes.
Tu mets des index sur :
- les colonnes utilisées dans
WHEREsouvent (ex: email) - les clés étrangères (user_id)
- les colonnes de tri (
ORDER BY) si c’est fréquent
Exemple :
CREATE INDEX idx_users_email ON users(email);
⚠️ Trop d’index = insert/update plus lents. Donc indexer intelligemment, pas au hasard.
9) Contraintes et intégrité : éviter les données “sales”
Une base doit protéger tes données. Exemples de contraintes :
- NOT NULL : champ obligatoire
- UNIQUE : pas de doublons (email)
- FOREIGN KEY : relation cohérente
- DEFAULT : valeur par défaut
Exemple : email unique :
ALTER TABLE users ADD UNIQUE (email);
Exemple : relation posts → users :
ALTER TABLE posts ADD CONSTRAINT fk_posts_user FOREIGN KEY (user_id) REFERENCES users(id);
✅ Résultat : impossible d’insérer un post avec