Une base de données relationnelle organise les données en tables reliées entre elles par des clés, et on les interroge avec SQL. C'est le modèle dominant depuis 50 ans pour les applications qui ont besoin de cohérence, d'intégrité et de requêtes structurées. Trois moteurs couvrent l'essentiel des besoins : SQLite (base embarquée dans un fichier), PostgreSQL (moteur objet-relationnel extensible) et MySQL (serveur SQL très répandu sur le web). Ce guide pose les bases du modèle relationnel, puis compare concrètement ces trois moteurs pour vous aider à choisir.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le modèle relationnel : tables, colonnes, clés primaires et étrangères
- Écrire des requêtes SQL de base : créer une table, insérer, interroger, joindre
- Connaître les garanties ACID et ce qu'elles signifient en pratique
- Différencier SQLite, PostgreSQL et MySQL sur le typage, les transactions, l'administration et les cas d'usage
- Choisir le bon moteur selon votre contexte (script local, application web, données complexes)
Dans quel contexte ?
Section intitulée « Dans quel contexte ? »Dès qu'une application a besoin de stocker des données structurées — comptes utilisateurs, commandes, inventaire, logs, configuration — la question du moteur de base de données se pose. Vous rencontrerez ce choix dans des situations très concrètes :
- Vous écrivez un script d'inventaire ou un outil CLI et vous voulez stocker les résultats localement
- Vous déployez une application web qui gère des utilisateurs, des produits et des commandes
- Vous montez un service métier avec des données complexes, des contraintes d'intégrité forte et des besoins d'extensibilité
- Vous administrez un serveur et vous devez choisir entre SQLite, PostgreSQL et MySQL pour un nouveau projet
Qu'est-ce qu'une base relationnelle ?
Section intitulée « Qu'est-ce qu'une base relationnelle ? »Une base de données relationnelle stocke les informations dans des tables. Chaque table représente un type d'objet (un utilisateur, un produit, une commande). Chaque ligne est un enregistrement, chaque colonne est un attribut.
Analogie : une table, c'est un tableur Excel très strict. Chaque colonne a un nom et un type imposé (texte, nombre, date), chaque ligne est un enregistrement, et il est interdit de mettre n'importe quoi dans n'importe quelle case.
Ce modèle a été formalisé en 1970 par Edgar F. Codd (chercheur chez IBM) dans son article fondateur sur le modèle relationnel. Le langage SQL (Structured Query Language) est né dans la foulée pour interroger ces tables. Cinquante ans plus tard, SQL reste le standard universel.
Les briques essentielles
Section intitulée « Les briques essentielles »| Concept | Rôle | Exemple |
|---|---|---|
| Table | Structure qui contient les données | clients, commandes |
| Colonne | Attribut d'une table (nom + type) | nom VARCHAR(100), prix DECIMAL(10,2) |
| Ligne | Un enregistrement | Le client "Alice", la commande n° 42 |
| Clé primaire | Identifiant unique d'une ligne | id INT PRIMARY KEY |
| Clé étrangère | Lien vers la clé primaire d'une autre table | client_id REFERENCES clients(id) |
| Contrainte | Règle d'intégrité (unicité, non-null, référence) | UNIQUE, NOT NULL, FOREIGN KEY |
Relations entre tables
Section intitulée « Relations entre tables »Les tables ne vivent pas isolées. Une clé étrangère relie une table à une autre :
Dans cet exemple, chaque commande pointe vers un client via client_id. C'est
l'intégrité référentielle : impossible de créer une commande pour un client
qui n'existe pas.
SQL en pratique : un exemple de bout en bout
Section intitulée « SQL en pratique : un exemple de bout en bout »Plutôt que des extraits isolés, voici un mini-domaine complet — clients, produits, commandes — pour voir les opérations fondamentales en action.
Créer les tables
Section intitulée « Créer les tables »CREATE TABLE clients ( id INT PRIMARY KEY, nom VARCHAR(100) NOT NULL, email VARCHAR(150) UNIQUE);
CREATE TABLE produits ( id INT PRIMARY KEY, nom VARCHAR(100) NOT NULL, prix DECIMAL(10, 2) NOT NULL);
CREATE TABLE commandes ( id INT PRIMARY KEY, client_id INT NOT NULL, produit_id INT NOT NULL, quantite INT DEFAULT 1, date_commande DATE NOT NULL, FOREIGN KEY (client_id) REFERENCES clients(id), FOREIGN KEY (produit_id) REFERENCES produits(id));Insérer des données
Section intitulée « Insérer des données »INSERT INTO clients (id, nom, email) VALUES (1, 'Alice Martin', 'alice@example.com'), (2, 'Bob Dupont', 'bob@example.com');
INSERT INTO produits (id, nom, prix) VALUES (1, 'Ordinateur portable', 999.99), (2, 'Clavier mécanique', 89.50);
INSERT INTO commandes (id, client_id, produit_id, quantite, date_commande) VALUES (1, 1, 1, 1, '2026-04-10'), (2, 1, 2, 2, '2026-04-11'), (3, 2, 2, 1, '2026-04-12');Interroger avec une jointure
Section intitulée « Interroger avec une jointure »La jointure (JOIN) est la requête qui tire parti des relations entre
tables. Elle permet de combiner les données de plusieurs tables en une seule
réponse :
SELECT c.nom AS client, p.nom AS produit, cmd.quantite, p.prix * cmd.quantite AS totalFROM commandes cmdJOIN clients c ON cmd.client_id = c.idJOIN produits p ON cmd.produit_id = p.idORDER BY cmd.date_commande;Résultat :
client | produit | quantite | total-----------------+---------------------+----------+-------- Alice Martin | Ordinateur portable | 1 | 999.99 Alice Martin | Clavier mécanique | 2 | 179.00 Bob Dupont | Clavier mécanique | 1 | 89.50Modifier et supprimer
Section intitulée « Modifier et supprimer »-- Mettre à jour un prixUPDATE produits SET prix = 849.99 WHERE id = 1;
-- Supprimer une commandeDELETE FROM commandes WHERE id = 3;Ce que garantit un SGBDR
Section intitulée « Ce que garantit un SGBDR »Un système de gestion de bases de données relationnelles (SGBDR) ne se contente pas de stocker des lignes. Il offre des garanties qui le distinguent d'un simple fichier CSV ou JSON.
Transactions et propriétés ACID
Section intitulée « Transactions et propriétés ACID »Une transaction regroupe plusieurs opérations en un bloc atomique :
BEGIN;UPDATE comptes SET solde = solde - 100 WHERE id = 1;UPDATE comptes SET solde = solde + 100 WHERE id = 2;COMMIT;Si l'une des opérations échoue, aucune n'est appliquée (ROLLBACK). C'est
le principe fondamental des propriétés ACID :
| Propriété | Signification | En pratique |
|---|---|---|
| Atomicité | Tout ou rien | Un virement ne peut pas débiter sans créditer |
| Cohérence | La base passe d'un état valide à un autre | Les contraintes sont toujours respectées |
| Isolation | Les transactions concurrentes ne se perturbent pas | Deux virements simultanés donnent le bon résultat |
| Durabilité | Un COMMIT est permanent | Même après un crash, les données sont là |
Un index accélère les recherches. Sans index, le moteur parcourt toute la table (scan séquentiel). Avec un index, il va directement à la bonne ligne — comme un index dans un livre :
CREATE INDEX idx_clients_email ON clients(email);Le type d'index le plus courant est le B-Tree, efficace pour les recherches
d'égalité (WHERE email = '...') et par plage (WHERE prix > 50).
PostgreSQL propose aussi GiST, GIN, BRIN et des index sur expressions.
MySQL utilise principalement B-Tree et hash (avec InnoDB). SQLite ne
supporte que B-Tree.
Contrôle d'accès
Section intitulée « Contrôle d'accès »La gestion des utilisateurs et des permissions diffère fondamentalement d'un moteur à l'autre :
PostgreSQL raisonne en rôles. Un rôle peut être un utilisateur (avec
LOGIN) ou un groupe (sans LOGIN). Les permissions se gèrent avec GRANT et
REVOKE :
CREATE ROLE lecteur;GRANT SELECT ON ALL TABLES IN SCHEMA public TO lecteur;
CREATE ROLE alice LOGIN PASSWORD 'motdepasse';GRANT lecteur TO alice;MySQL associe un utilisateur à un hôte ('user'@'host'). Les
permissions se gèrent aussi avec GRANT et REVOKE, mais la syntaxe diffère :
CREATE USER 'alice'@'%' IDENTIFIED BY 'motdepasse';GRANT SELECT ON labdb.* TO 'alice'@'%';SQLite n'a pas de gestion d'utilisateurs. C'est une bibliothèque embarquée : le contrôle d'accès repose sur les permissions du fichier au niveau du système d'exploitation :
# Seul l'utilisateur app peut lire/écrire la basechmod 600 /var/lib/monapp/data.dbchown app:app /var/lib/monapp/data.dbSQLite, PostgreSQL ou MySQL ?
Section intitulée « SQLite, PostgreSQL ou MySQL ? »C'est la question centrale. Ces trois moteurs sont tous relationnels et parlent SQL, mais ils n'ont pas la même nature ni les mêmes cas d'usage.
Vue d'ensemble
Section intitulée « Vue d'ensemble »| Critère | SQLite | PostgreSQL | MySQL |
|---|---|---|---|
| Nature | Bibliothèque embarquée (fichier local) | Serveur objet-relationnel extensible | Serveur SQL multi-utilisateur |
| Déploiement | Aucun — un fichier suffit | Service à installer et configurer | Service à installer et configurer |
| Multi-utilisateurs | Un seul écrivain à la fois | Oui, conçu pour | Oui, conçu pour |
| Typage | Dynamique (par valeur), mode STRICT optionnel | Statique, strict, types riches (JSON, array, range, hstore) | Statique, strict, types classiques |
| Extensibilité | Limitée | Très riche (extensions, types custom, PL/pgSQL, PL/Python) | Plugins, UDF |
| Réplication | Non intégrée | Streaming, logique, synchrone/asynchrone | Source/replica, Group Replication |
| Licence | Domaine public | PostgreSQL License (libre) | GPL v2 (Community) / Commercial (Enterprise) |
| Taille typique | Ko → quelques Go | Go → To | Go → To |
Quand choisir SQLite
Section intitulée « Quand choisir SQLite »SQLite est une bibliothèque C qui lit et écrit directement dans un fichier. Il n'y a pas de serveur, pas de configuration réseau, pas de gestion d'utilisateurs.
Cas d'usage typiques :
- Scripts et outils CLI qui stockent des résultats ou de la configuration
- Applications mobiles et embarquées
- Prototypage rapide et tests
- Fichiers de données locales (inventaire, cache, historique)
Limites :
- Un seul processus peut écrire à la fois (sérialisé, même en mode WAL)
- Pas de gestion d'accès réseau ni d'authentification
- Le typage est dynamique par défaut — une colonne
INTpeut contenir du texte siSTRICTn'est pas activé
Quand choisir PostgreSQL
Section intitulée « Quand choisir PostgreSQL »PostgreSQL est un moteur objet-relationnel avec une philosophie d'extensibilité et de conformité aux standards SQL. C'est le choix le plus riche fonctionnellement.
Cas d'usage typiques :
- Applications métier avec des données complexes (géospatiales, JSON, arrays)
- Systèmes nécessitant une intégrité forte et des contraintes avancées
- Projets avec des besoins d'extensibilité (types custom, extensions comme PostGIS, pgvector)
- Environnements DevOps / infrastructure (Terraform state, Vault, AWX, Gitea)
Points forts différenciants :
- Types avancés natifs :
JSONB,ARRAY,RANGE,UUID,INET - Index spécialisés : GiST, GIN, BRIN
- Réplication streaming et logique intégrée
EXPLAIN ANALYZEtrès détaillé pour l'optimisation
Quand choisir MySQL
Section intitulée « Quand choisir MySQL »MySQL est un serveur SQL très répandu, historiquement dominant dans l'écosystème web (LAMP, WordPress, Drupal, Magento). Il est simple à démarrer et dispose d'un large écosystème d'hébergement.
Cas d'usage typiques :
- Applications web classiques (CMS, e-commerce, blogs)
- Projets nécessitant un hébergement mutualisé (MySQL est quasi universel chez les hébergeurs)
- Stacks applicatives existantes qui s'appuient sur MySQL/MariaDB
- Réplication source/replica pour la lecture distribuée
Points à connaître :
- La terminologie a évolué : on parle désormais de source et replica (et non plus maître/esclave)
- La commande
CHANGE REPLICATION SOURCE TOremplaceCHANGE MASTER TO(déprécié depuis MySQL 8.0.23) - MariaDB est un fork de MySQL avec des divergences croissantes
Tableau de décision rapide
Section intitulée « Tableau de décision rapide »| Votre contexte | Moteur recommandé |
|---|---|
| Script local, outil CLI, prototypage | SQLite |
| Application web simple, hébergement mutualisé | MySQL |
| Application métier, données complexes, DevOps | PostgreSQL |
| Mobile, embarqué, IoT | SQLite |
| Intégrité forte, extensions, standards SQL | PostgreSQL |
| Stack existante MySQL/MariaDB | MySQL |
| Besoin de réplication avancée | PostgreSQL ou MySQL |
À retenir
Section intitulée « À retenir »- Une base relationnelle organise les données en tables reliées par des clés, interrogées en SQL
- Les opérations SQL de base —
CREATE TABLE,INSERT,SELECT JOIN,UPDATE,DELETE— sont portables entre moteurs - Les propriétés ACID garantissent la fiabilité des transactions, mais le comportement exact de l'isolation varie selon le moteur
- SQLite est une bibliothèque embarquée (fichier local, zéro configuration, un seul écrivain) — idéale pour scripts et outils
- PostgreSQL est un moteur objet-relationnel extensible (types riches, index spécialisés, réplication intégrée) — le plus complet fonctionnellement
- MySQL est un serveur SQL très répandu (écosystème web, hébergement facile, réplication source/replica) — le plus courant en hébergement
- Le typage diffère : dynamique par défaut sur SQLite, strict sur PostgreSQL et MySQL
- Le contrôle d'accès diffère radicalement : rôles (PostgreSQL), user@host (MySQL), permissions fichier (SQLite)