Cahier d'histoire de l'informatique

SQL, le langage des données

Comptes bancaires, réservations de train, dossiers médicaux, messages de votre téléphone, catalogues des sites marchands : presque toutes les données structurées du monde sont rangées dans des bases de données relationnelles et interrogées en SQL, un langage né chez IBM au début des années 1970. Cinq planches pour comprendre comment on organise les tables, comment le moteur les recolle et les retrouve vite, comment il protège les données quand plusieurs personnes écrivent en même temps, puis pour écrire vos propres requêtes.

Dire ce que l'on veut, pas comment le chercher

En 1970, Edgar Codd, mathématicien chez IBM, propose le modèle relationnel : les données sont rangées dans des tables (des « relations » au sens mathématique), et l'on obtient de nouvelles tables à partir des anciennes par quelques opérations : choisir des lignes, choisir des colonnes, recoller deux tables. En 1974, Donald Chamberlin et Raymond Boyce en tirent un langage proche de l'anglais, SEQUEL, rebaptisé SQL (Structured Query Language). Sa force est d'être déclaratif : on décrit le résultat voulu, et c'est le moteur qui choisit la meilleure façon de le calculer. Normalisé en 1986, enrichi régulièrement depuis, SQL a survécu à toutes les modes de l'informatique.

Une requête SQL et son exécution : la question est écrite dans un ordre (SELECT, FROM, WHERE…), le moteur la calcule dans un autre. Les lignes des tables traversent les étapes successives jusqu'au résultat.
Planche 1

Le modèle relationnel : une information à un seul endroit

1970 – 1974

Une petite librairie en ligne note ses ventes dans un tableur : une ligne par article vendu, avec la date, le client, sa ville, le produit et son prix. Simple, mais le nom de chaque client et le prix de chaque produit sont recopiés à chaque vente. Codd propose de normaliser : découper ce grand tableau en tables séparées (clients, produits, commandes, lignes de commande), reliées par des numéros, de sorte que chaque information ne soit écrite qu'une fois. Lancez la normalisation, puis faites déménager une cliente.

D'abord la grande table : les valeurs recopiées plusieurs fois sont teintées. Après normalisation, les quatre tables liées ; les flèches relient les numéros (clés étrangères) aux tables qu'ils désignent. Lors du déménagement, les cases à modifier s'allument.
Cases stockées : grande table / tables normalisées
—
Cases à modifier pour le déménagement
—
Contrôle : la jointure des 4 tables redonne exactement la grande table (comparée à SQLite)
—
Ce qu'il faut retenir. Dans la grande table, oublier une seule des lignes d'Amélie lors de son déménagement suffit à rendre les données contradictoires : c'est l'anomalie de mise à jour. Dans les tables normalisées, sa ville n'est écrite qu'une fois. Chaque table a une clé primaire (le numéro id) qui identifie chaque ligne, et les autres tables y renvoient par des clés étrangères (client_id, produit_id). Les formes normales, définies par Codd en 1971-1972, sont les règles de ce découpage. Rien n'est perdu : une requête avec JOIN reconstitue la grande table à la demande.
Planche 2

La jointure : comment le moteur recolle les tables

1976 – 1984

La requête SELECT … FROM commandes JOIN clients ON commandes.client_id = clients.id associe à chaque commande son client. SQL ne dit pas comment faire : c'est le moteur qui choisit un algorithme. La boucle imbriquée compare chaque commande à chaque client ; la jointure par hachage range d'abord les clients dans une table de hachage, indexée par leur numéro, puis va chercher directement le bon client pour chaque commande. Comparez le nombre d'opérations.

12
Boucle imbriquée : la grille de toutes les paires (commande, client), chaque case est une comparaison, en vert quand les numéros correspondent. Hachage : les clients rangés dans des « cases » selon leur numéro, puis chaque commande va droit à la sienne.
Opérations effectuées
—
Lignes du résultat
—
Pour 1 million de commandes et 100 000 clients
—
Contrôle : résultat identique à celui de SQLite
—
Ce qu'il faut retenir. Pour n commandes et m clients, la boucle imbriquée fait n × m comparaisons, la jointure par hachage environ n + m opérations : sur de grandes tables, la différence se compte en heures. Le choix revient à l'optimiseur de requêtes, dont le premier fut conçu pour le prototype System R d'IBM (Patricia Selinger, 1979) : il estime le coût de chaque plan possible à partir de statistiques sur les tables et retient le moins cher. C'est tout l'intérêt d'un langage déclaratif : la même requête, écrite en 1986, profite des algorithmes inventés depuis.
Planche 3

Les index : retrouver une ligne parmi des milliards

1970 – 1979

Sans précaution, chercher un client par son numéro oblige à lire toute la table : c'est un balayage. La commande CREATE INDEX construit un arbre B (Rudolf Bayer et Edward McCreight, 1970), qui joue le rôle de l'index alphabétique d'un livre : chaque nœud contient quelques clés triées et oriente vers le bon sous-arbre. Les bases de données utilisent une variante, l'arbre B+, où toutes les lignes sont dans les feuilles. Réglez le nombre de branches par nœud et cherchez une clé.

4
42
Un index sur 60 clés. Le chemin de la recherche descend de la racine à la feuille ; en dessous, la même recherche par balayage, case par case.
Nombre de nœuds lus pour trouver une ligne, selon la taille de la table (échelle logarithmique), pour un index à 4 branches et un index réaliste à 500 branches par nœud.
Nœuds visités / profondeur de l'arbre
—
Cases lues par balayage
—
Contrôle : profondeurs calculées par Python en construisant les arbres (25 cas)
—
Ce qu'il faut retenir. Avec f branches par nœud, un arbre de profondeur h contient jusqu'à fh clés : la profondeur ne croît que comme le logarithme de la taille. Les vrais nœuds occupent une page de disque de quelques kilo-octets et contiennent des centaines de clés ; trois ou quatre lectures suffisent alors pour retrouver une ligne parmi des milliards. Un index a un prix : il occupe de la place et doit être mis à jour à chaque insertion. On indexe donc les colonnes souvent cherchées (numéros, noms, dates), et l'optimiseur décide seul d'utiliser l'index ou non.
Planche 4

Les transactions : quand deux personnes écrivent en même temps

1976 – 1983

Un compte contient 100 €. Au même instant, un premier guichet y dépose 50 € et un second y retire 30 €. Chaque opération fait trois pas : lire le solde, calculer le nouveau, l'écrire. Selon l'ordre dans lequel l'ordinateur entremêle ces six pas, le résultat peut être faux ! Les bases de données regroupent les opérations en transactions et posent des verrous pour que tout se passe comme si elles s'exécutaient l'une après l'autre. Choisissez un ordre d'exécution, avec ou sans verrou.

Les deux guichets (dépôt en bleu, retrait en rouge) et le compte au centre. Chaque guichet garde le solde lu dans sa mémoire locale ; avec verrou, le second attend que le premier ait fini.
Solde final pour les 20 ordres possibles des six pas, sans verrou (gris) et avec verrou (vert). Le bon résultat est 120 €.
Solde final de cet ordre
—
Ordres donnant un résultat faux, sans verrou / avec verrou
—
Contrôle : les 20 ordres simulés par Python
—
Ce qu'il faut retenir. Sans protection, 18 ordres sur 20 donnent un résultat faux : c'est la mise à jour perdue, l'un des guichets écrase le travail de l'autre. Jim Gray (prix Turing 1998) a fondé la théorie des transactions, résumée en 1983 par l'acronyme ACID : atomicité (tout ou rien), cohérence (les règles restent respectées), isolation (les transactions ne se voient pas à moitié faites), durabilité (une fois validée, une transaction survit à une panne, grâce à un journal écrit sur disque avant toute modification). En SQL, on écrit BEGIN, les instructions, puis COMMIT pour valider ou ROLLBACK pour tout annuler.
Planche 5 · signature

À vous d'écrire des requêtes

2026

Voici la base complète de la librairie : clients, produits, commandes et lignes de commande. Un petit moteur SQL, écrit pour cette page, exécute vos requêtes dans le navigateur et montre l'ordre réel de leur exécution. Commencez par les exemples, puis relevez les huit défis : le moteur compare votre résultat à la bonne réponse, calculée par SQLite. Il comprend SELECT, DISTINCT, FROM, JOIN, LEFT JOIN, WHERE, GROUP BY, HAVING, ORDER BY, LIMIT, les fonctions COUNT, SUM, AVG, MIN, MAX, LENGTH, UPPER, LOWER, ROUND, et les opérateurs LIKE, IN, BETWEEN, IS NULL.

Les quatre tables et leurs liens ; les colonnes utilisées par la requête sont surlignées, et les étapes de l'exécution s'affichent avec le nombre de lignes après chacune.

Résultat

Message du moteur
—
Défis réussis
0 / 8
Contrôle : les 8 exemples et les 8 solutions donnent le même résultat que SQLite
—
Ce qu'il faut retenir. Une requête se lit dans l'ordre où le moteur l'exécute : d'abord FROM et JOIN (de quelles tables part-on ?), puis WHERE (quelles lignes garder ?), GROUP BY et HAVING (comment regrouper, quels groupes garder ?), enfin SELECT, ORDER BY et LIMIT (que montrer, dans quel ordre, combien ?). COUNT(*) compte les lignes, COUNT(colonne) ignore les valeurs absentes (NULL), ce qui permet de compter zéro commande avec LEFT JOIN. Sans ORDER BY, l'ordre des lignes du résultat n'est pas garanti : le moteur de comparaison des défis n'en tient compte que lorsque l'énoncé demande un tri. En entreprise, on ne colle jamais directement un texte saisi par un utilisateur dans une requête : on utilise des requêtes paramétrées, pour éviter les injections SQL.

Où trouve-t-on SQL ?

Les grandes bases

Oracle (1979), IBM Db2 (1983), Microsoft SQL Server (1989), puis les bases libres PostgreSQL (1996, héritière de Postgres, 1986) et MySQL (1995) gèrent banques, administrations, sites Web et logiciels de gestion.

Dans la poche

SQLite (2000), une base logée dans un simple fichier, est intégrée à tous les téléphones, aux navigateurs et à d'innombrables applications : c'est probablement le moteur SQL le plus répandu au monde.

L'analyse des données

Entrepôts de données, tableaux de bord, statistiques : les analystes interrogent en SQL des milliards de lignes dans le nuage, et les outils de science des données (Python, R) parlent tous SQL.

Toujours vivant

La norme SQL:2023 a ajouté les requêtes sur les graphes (SQL/PGQ) et un vrai type JSON ; les assistants d'IA traduisent aujourd'hui des questions en français en requêtes SQL, à vérifier avant usage.

Frise des jalons

Pour aller plus loin

Les résultats des requêtes, la table reconstituée, les profondeurs des arbres et les 20 exécutions de la planche 4 ont été calculés en Python (avec SQLite) au moment de la fabrication de la page ; votre navigateur refait tous ces calculs et les compare.