Deux philosophies de base de données
SQLite et MySQL parlent tous les deux le SQL et stockent leurs données sous forme de lignes dans des tables, mais leur place dans un système n'a rien à voir. SQLite est une bibliothèque : votre application s'y lie directement et lit un fichier sur le disque. MySQL, lui, est un serveur : un processus à part auquel on se connecte via une socket ou par le réseau.
Cette seule différence change absolument tout : l'installation, le nombre d'écritures simultanées possibles, la façon de faire les sauvegardes, le déploiement. Au fond, la plupart des questions autour de SQLite ou MySQL reviennent en fait à comparer une base de données embarquée et une architecture client-serveur.
-- SQLite : ouvrez un fichier, vous avez une base de données.
sqlite3 app.db
-- MySQL : connectez-vous à un serveur en cours d'exécution.
mysql -h localhost -u root -p
La commande SQLite ouvre (ou crée) un fichier. La commande MySQL, elle, ouvre une connexion vers un processus qui doit déjà tourner, être configuré et accepter les connexions.
Architecture : base de données embarquée vs serveur
Dans une appli SQLite, le moteur de base de données tourne à l'intérieur de votre programme. Pas de port, pas de démon, pas de systemctl start. Un appel à la bibliothèque sqlite3 lit et écrit directement les pages d'un fichier sur le disque.
MySQL fonctionne à l'inverse. Le serveur mysqld détient les données, gère les connexions, applique les permissions, exécute le planificateur de requêtes et s'occupe du verrouillage. Votre application est un client qui envoie des chaînes SQL sur le réseau et reçoit les lignes de résultat en retour.
Les conséquences concrètes :
- Déploiement. SQLite est livré avec votre appli — un binaire, un fichier. MySQL exige un serveur séparé à installer, sécuriser, superviser et sauvegarder.
- Accès réseau. MySQL expose un port, ce qui permet à plusieurs serveurs applicatifs de se connecter à la même base. SQLite part du principe qu'un seul processus (ou quelques processus qui coopèrent) tourne sur la même machine.
- Permissions. MySQL propose des utilisateurs, des rôles et des instructions
GRANT. Côté SQLite, le seul système de permissions, ce sont les droits du système de fichiers sur le fichier de base.
Aucune des deux approches n'est « meilleure ». Elles répondent à des problèmes différents.
Concurrence et écritures
C'est là que les deux moteurs prennent vraiment des chemins opposés. Le moteur InnoDB de MySQL pratique le verrouillage au niveau ligne — plusieurs connexions peuvent écrire sur des lignes différentes en même temps sans se bloquer.
SQLite, lui, sérialise les écritures au niveau de la base entière. Un seul rédacteur à la fois, point. Les lecteurs peuvent travailler en parallèle du rédacteur (surtout en mode WAL), mais un deuxième rédacteur doit attendre son tour.
-- SQLite : cela fonctionne très bien pour de nombreux lecteurs, un seul rédacteur à la fois.
PRAGMA journal_mode = WAL;
-- MySQL : plusieurs rédacteurs, verrouillage à granularité fine.
-- (Aucune configuration particulière — InnoDB le fait par défaut.)
Pour une appli avec un ou deux processus qui font des écritures modérées — un outil desktop, une appli mobile, un petit CMS — les écritures sérialisées de SQLite sont en général largement assez rapides pour que vous ne voyiez jamais la différence. En revanche, sur un service web chargé avec des centaines de connexions qui insèrent des commandes ou mettent à jour des sessions en parallèle, le verrouillage au niveau ligne de MySQL fait toute la différence entre « ça tourne » et « tout le monde fait la queue derrière un seul verrou ».
Les types de données
MySQL propose une longue liste de types stricts : TINYINT, INT, BIGINT, VARCHAR(n), DATETIME, DECIMAL(p,s), BLOB, JSON, et bien d'autres. Déclarez une colonne INT et MySQL refusera tout net une chaîne de caractères.
SQLite, lui, fonctionne avec ce qu'on appelle l'affinité de type. Les types de colonnes sont des indications, pas des règles imposées. Vous pouvez parfaitement glisser une chaîne dans une colonne INTEGER, SQLite la stockera sans broncher (sauf si vous activez les tables STRICT, arrivées avec la version 3.37).
Les deux insertions réussissent sans broncher. Cette souplesse est pratique quand on prototype, mais déroutante si l'on s'attend à un typage strict au niveau de la base. Utilisez les tables STRICT quand vous voulez retrouver dans SQLite la rigueur d'un MySQL.
Les différences de syntaxe que vous allez vraiment croiser
L'essentiel du SQL de base — SELECT, JOIN, WHERE, GROUP BY — est identique. Les écarts se concentrent sur quelques points précis :
- Clés primaires auto-incrémentées. SQLite utilise
INTEGER PRIMARY KEY(qui s'auto-incrémente par défaut). MySQL, lui, exigeINT AUTO_INCREMENT PRIMARY KEY. - Délimiteurs de chaînes et d'identifiants. MySQL accepte les backticks pour les identifiants (
`table`). SQLite suit la norme SQL et emploie les guillemets doubles ("table"). - Fonctions de date. MySQL propose
NOW(),CURDATE(),DATE_ADD(). SQLite mise surdatetime('now'),date('now'),datetime('now', '+1 day'). - Syntaxe de
LIMIT. Les deux gèrentLIMIT n OFFSET m: aucune surprise de ce côté-là. - Booléens. MySQL fournit un type
BOOLEAN(en réalité un alias pourTINYINT(1)). SQLite, de son côté, stocke les booléens sous forme de0et1dans des colonnesINTEGER.
-- MySQL
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
created_at DATETIME DEFAULT NOW()
);
-- SQLite
CREATE TABLE users (
id INTEGER PRIMARY KEY,
created_at TEXT DEFAULT (datetime('now'))
);
Même intention, vocabulaire différent. Le modèle mental reste le même, seule la syntaxe demande quelques petits ajustements.
Performances SQLite vs MySQL : ça dépend de la question
« SQLite est-il plus rapide que MySQL ? » n'a pas de réponse unique.
Pour un seul processus qui lit et écrit en local, SQLite est souvent plus rapide — pas de saut réseau, pas de communication inter-processus, pas d'analyseur de requêtes qui tourne dans un espace d'adressage séparé. Un SELECT dans SQLite, c'est essentiellement un appel de fonction.
Avec beaucoup de connexions concurrentes qui écrivent dans la même base, MySQL prend l'avantage grâce au verrouillage au niveau de la ligne. Le modèle « un seul rédacteur à la fois » de SQLite fait vite apparaître la contention sur ce genre de charge.
Pour des charges principalement en lecture avec le mode WAL activé, SQLite passe à l'échelle étonnamment bien — les lecteurs ne se bloquent ni entre eux ni avec l'unique rédacteur. Pas mal de sites en production servent du vrai trafic depuis SQLite.
Ne choisissez pas sur la foi de benchmarks lus en ligne. Choisissez selon votre véritable schéma d'accès.
Quand utiliser SQLite ou MySQL
Optez pour SQLite quand :
- La base vit à côté d'une seule application (appli mobile, outil desktop, CLI, petit site web).
- Vous voulez un déploiement sans configuration — il suffit de livrer le fichier.
- Les lectures dominent largement les écritures, ou les écritures sont rares.
- Vous avez besoin d'une base de tests embarquée qui reflète le SQL de production.
- Vous prototypez et ne voulez pas vous embêter avec un serveur pour l'instant.
Optez pour MySQL quand :
- Plusieurs serveurs applicatifs doivent partager la même base.
- Vous avez beaucoup d'écritures concurrentes.
- Vous avez besoin d'une gestion fine des permissions utilisateurs et des rôles.
- Vous construisez sur une stack (LAMP, configurations cloud managées classiques) qui attend MySQL.
- L'outillage opérationnel — réplication, restauration à un instant T, supervision — est une exigence forte.
Une heuristique grossière : si vos besoins de stockage tiennent dans « une appli, un disque », SQLite suffira sans doute. Si vous diriez plutôt « un service, avec des opérateurs derrière », partez sur MySQL (ou PostgreSQL).
Migrer SQLite vers MySQL (et inversement)
Démarrer sur SQLite puis passer à MySQL plus tard est un chemin bien balisé — et un plan tout à fait raisonnable. Les schémas se traduisent moyennant quelques ajustements, et les données s'exportent proprement via .dump depuis le CLI SQLite. Vous passerez surtout du temps à corriger la syntaxe d'auto-incrément, les fonctions de date, et les quelques fonctionnalités spécifiques à SQLite (index partiels aux formes exotiques, WITHOUT ROWID, tables STRICT) qui n'ont pas d'équivalent direct côté MySQL.
Dans l'autre sens — de MySQL vers SQLite — c'est plus rare mais tout aussi faisable, généralement pour de l'analyse hors ligne, des copies embarquées d'un sous-ensemble de données, ou des fixtures de test.
L'idée à retenir : choisir SQLite aujourd'hui ne vous enferme pas. Le SQL que vous écrivez se transfère, et votre compréhension aussi.
La suite : SQLite vs PostgreSQL
MySQL est la comparaison la plus fréquente, mais PostgreSQL est l'autre base qu'on oppose souvent à SQLite — et là, les différences sont d'une autre nature. C'est le sujet de la page suivante.
Questions fréquentes
Quelle est la vraie différence entre SQLite et MySQL ?
SQLite est une base embarquée : un simple fichier que votre application lit et écrit directement, sans serveur. MySQL fonctionne en mode client-serveur : un processus mysqld tourne en arrière-plan, écoute sur un port, et votre appli dialogue avec lui via le réseau. Cette différence d'architecture conditionne à peu près tous les autres compromis entre les deux.
SQLite est-il plus rapide que MySQL ?
Pour un seul processus qui fait des lectures et de petites écritures, oui : SQLite évite l'aller-retour réseau et la communication inter-processus, donc il est souvent plus véloce. En revanche, dès qu'on a beaucoup d'écritures concurrentes, MySQL prend largement le dessus, car SQLite sérialise les écritures au niveau de la base. Tout dépend de votre charge de travail, pas du moteur dans l'absolu.
Dans quels cas faut-il privilégier SQLite plutôt que MySQL ?
SQLite est tout indiqué pour les applis embarquées, le mobile, les outils desktop, les utilitaires en ligne de commande, les caches locaux, les tests, et les sites web de petite à moyenne taille avec un seul serveur applicatif. On passe à MySQL dès qu'il faut plusieurs serveurs applicatifs qui attaquent la même base, une gestion fine des permissions utilisateurs, ou quand la charge en écriture devient suffisamment lourde pour exiger un verrouillage au niveau de la ligne.
Peut-on migrer plus tard de SQLite vers MySQL ?
Oui, c'est un parcours très classique. Les dialectes SQL se recoupent largement sur CREATE TABLE, INSERT et SELECT, mais il faudra adapter les types (INTEGER PRIMARY KEY devient INT AUTO_INCREMENT), les fonctions de date, et toutes les spécificités SQLite comme WITHOUT ROWID ou les index uniques partiels. Des outils comme pgloader et quelques scripts de dump maison font le gros du travail.