Back-end · 5 mondes · 15 étapes
Bases de données & SQL
Interroger, relier, modifier et concevoir des données, avec une vraie base SQLite.
Progression
0 %
0/15 étapes terminées
Avancé · 12 min de lecture
SQL en production
Plans d'exécution, injections et migrations
1Définition
En production, SQL pose trois questions de plus : la performance (la base lit-elle toute la table ?), la sécurité (une saisie peut-elle devenir une requête ?) et l'évolution (comment changer le schéma sans interrompre le service ?).
2Principes fondamentaux
01
Lire le plan d'exécution
EXPLAIN QUERY PLAN montre si la base parcourt toute la table (SCAN) ou consulte un index (SEARCH).
02
Jamais de concaténation de saisies
Une requête construite en collant du texte saisi est une porte ouverte à l'injection SQL. On utilise des paramètres.
03
Des migrations versionnées
Chaque changement de schéma est un fichier numéroté, appliqué dans l'ordre sur chaque environnement.
04
Sauvegarder et tester la restauration
Une sauvegarde non restaurée pour essai est une supposition.
3Exemples pratiques
L'injection SQL
1-- Code vulnérable : la saisie est collée dans la requête2-- saisie = "x' OR '1'='1"3SELECT * FROM joueurs WHERE pseudo = 'x' OR '1'='1';4-- renvoie TOUS les joueurs5 6-- Code sûr : la saisie est un paramètre, jamais du SQL7-- SELECT * FROM joueurs WHERE pseudo = ?Avec un paramètre, la base traite la saisie comme une valeur, quoi qu'elle contienne. C'est la faille la plus exploitée du web depuis vingt ans.
Voir le plan
1EXPLAIN QUERY PLAN2SELECT * FROM resultats WHERE joueur_id = 1;3-- SCAN resultats (sans index)4-- SEARCH resultats USING INDEX idx_resultats_joueur (joueur_id=?)SCAN signifie « je lis tout » ; SEARCH, « je vais droit au but ». La différence se compte en secondes sur une grande table.
4Erreurs courantes
Coller une saisie dans une requête
À éviter
`SELECT * FROM joueurs WHERE pseudo = '${saisie}'`À faire
db.query("SELECT * FROM joueurs WHERE pseudo = ?", [saisie])Pourquoi : L'injection SQL permet de lire, modifier ou détruire toute la base.
Modifier le schéma à la main en production
À éviter
-- ALTER TABLE tapé dans la console du serveurÀ faire
-- une migration versionnée, testée, puis appliquéePourquoi : Personne ne sait plus quel environnement a quel schéma.
5Subtilités à connaître
- ◆Les ORM (Prisma, Drizzle) génèrent les requêtes et les paramètres pour toi — mais une requête lente reste lente : il faut savoir lire ce qu'ils produisent.
- ◆Le problème « N+1 » : une requête par ligne affichée au lieu d'une jointure. Cent joueurs, cent une requêtes.
- ◆PostgreSQL, la base de Supabase, parle le même SQL que ce cours, avec beaucoup plus de types et de fonctions.
6Techniques d'expert
Les fonctions de fenêtre
Classer sans perdre les lignes : RANK() OVER (ORDER BY score DESC) donne le rang de chaque joueur dans le même résultat.
SELECT pseudo, score, RANK() OVER (ORDER BY score DESC) AS rangFROM joueurs;Les requêtes nommées (CTE)
WITH découpe une requête complexe en étapes nommées, lisibles une par une.
WITH totaux AS ( SELECT joueur_id, COUNT(*) AS missions FROM resultats GROUP BY joueur_id)SELECT j.pseudo, t.missionsFROM totaux t JOIN joueurs j ON j.id = t.joueur_id;Des requêtes paramétrées
Dans le code applicatif, la requête et les valeurs voyagent séparément.
const joueur = await db .prepare("SELECT * FROM joueurs WHERE pseudo = ?") .get(saisie);7Sur le terrain
- Le backend prévu pour Sys-Code repose sur PostgreSQL : les tables joueurs, progression et porte-monnaie de la documentation sont exactement celles de ce cours.
- La majorité des lenteurs d'application viennent d'un index manquant ou d'une requête par ligne au lieu d'une jointure.
- L'injection SQL figure depuis vingt ans dans le classement des failles les plus exploitées : les requêtes paramétrées la rendent impossible.
8Vérifie ta compréhension
Question 1/3
Score 0
Comment se protéger de l'injection SQL ?
Envie d'essayer ? Ouvre le Labo et recopie les exemples pour les modifier.