Zwei grundverschiedene Architekturen
SQLite und MySQL sprechen beide SQL und legen Daten in Tabellen ab – wie sie sich aber in ein System einfügen, ist völlig unterschiedlich. SQLite ist eine Bibliothek: Deine Anwendung bindet sie ein und liest aus einer Datei auf der Festplatte. MySQL dagegen ist ein Server, also ein eigener Prozess, mit dem du dich über einen Socket oder über das Netzwerk verbindest.
Aus genau diesem einen Unterschied folgt alles Weitere: die Installation, wie viele Schreibvorgänge gleichzeitig möglich sind, wie Backups laufen und wie das Deployment aussieht. Die meisten Fragen rund um SQLite vs MySQL sind in Wahrheit Fragen zum Vergleich Embedded-Datenbank vs Client-Server.
-- SQLite: Datei öffnen, schon hast du eine Datenbank.
sqlite3 app.db
-- MySQL: Verbindung zu einem laufenden Server herstellen.
mysql -h localhost -u root -p
Der SQLite-Befehl öffnet (oder erstellt) eine Datei. Der MySQL-Befehl baut dagegen eine Verbindung zu einem Prozess auf, der bereits laufen, konfiguriert sein und Logins akzeptieren muss.
Architektur: Embedded vs. Client-Server
Bei einer SQLite-Anwendung läuft die Datenbank-Engine innerhalb deines Programms. Kein Port, kein Daemon, kein systemctl start. Ein Aufruf der sqlite3-Bibliothek liest und schreibt Pages direkt aus einer Datei auf der Festplatte.
Bei MySQL ist es genau umgekehrt. Der mysqld-Server hält die Daten, verwaltet Verbindungen, erzwingt Berechtigungen, führt den Query-Planner aus und kümmert sich ums Locking. Deine Anwendung ist ein Client, der SQL-Strings über die Leitung schickt und Ergebniszeilen zurückbekommt.
Was das in der Praxis bedeutet:
- Deployment. SQLite wird mit deiner App ausgeliefert — ein Binary, eine Datei. MySQL braucht einen separaten Server, den du installieren, absichern, überwachen und sichern musst.
- Netzwerkzugriff. MySQL stellt einen Port bereit, sodass mehrere Application-Server auf dieselbe Datenbank zugreifen können. SQLite geht von einem Prozess (oder wenigen kooperierenden Prozessen) auf derselben Maschine aus.
- Berechtigungen. MySQL bringt Benutzer, Rollen und
GRANT-Statements mit. Bei SQLite sind die einzigen Berechtigungen die Dateirechte des Betriebssystems auf der Datenbankdatei.
Keine der beiden Architekturen ist „besser". Sie lösen unterschiedliche Probleme.
Nebenläufigkeit und Schreibzugriffe
Genau hier gehen die beiden richtig auseinander. Die InnoDB-Engine von MySQL arbeitet mit Row-Level-Locking — viele Verbindungen können gleichzeitig in verschiedene Zeilen schreiben, ohne sich gegenseitig zu blockieren.
SQLite serialisiert Schreibzugriffe auf Datenbank-Ebene. Immer nur ein Writer gleichzeitig, Punkt. Leser können parallel zum Writer laufen (vor allem im WAL-Modus), aber ein zweiter Writer muss warten, bis er an der Reihe ist.
-- SQLite: Funktioniert gut für viele Leser, einen Schreiber zur Zeit.
PRAGMA journal_mode = WAL;
-- MySQL: Viele Schreiber, feinkörnige Sperren.
-- (Keine spezielle Einrichtung – InnoDB macht das standardmäßig.)
Bei einer App mit ein, zwei Prozessen und überschaubarem Schreibaufkommen – einem Desktop-Tool, einer Mobile-App, einem kleinen CMS – sind die serialisierten Writes von SQLite in der Regel so schnell, dass es überhaupt nicht auffällt. Bei einem stark frequentierten Webservice mit Hunderten parallelen Verbindungen, die Bestellungen einfügen oder Sessions aktualisieren, macht das Row-Level-Locking von MySQL dagegen den Unterschied zwischen „läuft rund" und „alles steht hinter einem einzigen Lock in der Warteschlange".
Datentypen: SQLite vs MySQL im Vergleich
MySQL bringt eine lange, strenge Liste an Datentypen mit: TINYINT, INT, BIGINT, VARCHAR(n), DATETIME, DECIMAL(p,s), BLOB, JSON und viele mehr. Deklarierst du eine Spalte als INT, weist MySQL einen String konsequent ab.
SQLite arbeitet stattdessen mit Type Affinity. Spaltentypen sind hier eher Empfehlungen als feste Regeln. Du kannst problemlos einen String in eine INTEGER-Spalte schreiben, und SQLite speichert ihn (es sei denn, du nutzt explizit STRICT-Tabellen, die ab Version 3.37 verfügbar sind).
Beide Zeilen werden problemlos eingefügt. Diese Flexibilität ist praktisch beim Prototyping, aber überraschend, wenn man auf Typsicherheit auf Datenbankebene zählt. Wenn du eine MySQL-ähnliche Durchsetzung in SQLite willst, nimm STRICT-Tabellen.
Syntaxunterschiede, die dir in der Praxis begegnen
Der Großteil von Standard-SQL – SELECT, JOIN, WHERE, GROUP BY – ist identisch. Die Unterschiede zwischen SQLite und MySQL konzentrieren sich auf ein paar bestimmte Bereiche:
- Auto-Increment für Primärschlüssel. SQLite nutzt
INTEGER PRIMARY KEY(das standardmäßig automatisch hochzählt). MySQL verwendet stattdessenINT AUTO_INCREMENT PRIMARY KEY. - Anführungszeichen für Bezeichner. MySQL erlaubt Backticks für Bezeichner (
`table`). SQLite verwendet doppelte Anführungszeichen ("table") gemäß SQL-Standard. - Datumsfunktionen. MySQL bietet
NOW(),CURDATE()undDATE_ADD(). SQLite arbeitet mitdatetime('now'),date('now')unddatetime('now', '+1 day'). LIMIT-Syntax. Beide unterstützenLIMIT n OFFSET m– hier sind sie kompatibel.- Boolesche Werte. MySQL kennt
BOOLEAN(ein Alias fürTINYINT(1)). SQLite speichert Wahrheitswerte als0und1inINTEGER-Spalten.
-- 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'))
);
Gleiche Idee, andere Schlüsselwörter. Das mentale Modell bleibt gleich, nur die Syntax muss man leicht anpassen.
Performance: Kommt drauf an, was du fragst
"Ist SQLite schneller als MySQL?" – darauf gibt es keine pauschale Antwort.
Bei einem einzelnen Prozess, der lokal liest und schreibt, ist SQLite oft schneller. Es gibt keinen Netzwerk-Hop, keine Interprozesskommunikation, keinen Query-Parser, der in einem eigenen Adressraum läuft. Ein SELECT in SQLite ist im Grunde nur ein Funktionsaufruf.
Wenn dagegen viele parallele Verbindungen gleichzeitig in dieselbe Datenbank schreiben, zieht MySQL dank Row-Level Locking vorbei. SQLite erlaubt nur einen Writer gleichzeitig – bei dieser Art von Last wird Contention schnell zum Problem.
Bei lesedominierten Workloads mit aktiviertem WAL-Modus skaliert SQLite erstaunlich gut: Leser blockieren sich weder gegenseitig noch den einen Writer. Es gibt jede Menge Production-Seiten, die echten Traffic aus SQLite ausliefern.
Such dir nicht anhand irgendwelcher Online-Benchmarks die Datenbank aus. Such sie dir nach deinem tatsächlichen Zugriffsmuster aus.
Wann SQLite, wann MySQL?
Greif zu SQLite, wenn:
- die Datenbank direkt neben einer einzigen Anwendung lebt (Mobile App, Desktop-Tool, CLI, kleine Website).
- du Deployment ohne Konfigurationsaufwand willst – einfach die Datei ausliefern.
- Lesezugriffe deutlich überwiegen oder Schreibzugriffe selten sind.
- du eine eingebettete Testdatenbank brauchst, die das Production-SQL widerspiegelt.
- du gerade prototypst und dich noch nicht mit einem Server beschäftigen willst.
Greif zu MySQL, wenn:
- mehrere Application-Server sich eine Datenbank teilen müssen.
- du viele parallele Writer hast.
- du feingranulare User-Rechte und Rollenverwaltung brauchst.
- dein Stack (LAMP, gängige Managed-Cloud-Setups) MySQL erwartet.
- Operations-Werkzeuge wie Replikation, Point-in-Time Recovery und Monitoring zwingend dazugehören.
Eine grobe Faustregel: Wenn du deinen Speicherbedarf als "eine App, eine Platte" beschreiben würdest, reicht SQLite vermutlich. Wenn du eher "ein Service mit Operations-Team" sagst, dann MySQL (oder PostgreSQL).
Von SQLite zu MySQL migrieren
Mit SQLite anzufangen und später auf MySQL zu wechseln, ist ein gut erprobter Weg – und ein völlig vernünftiger Plan. Die Schemas lassen sich mit kleinen Anpassungen übertragen, und die Daten exportierst du sauber mit .dump aus der SQLite-CLI. In der Praxis fixt du hauptsächlich Auto-Increment-Syntax, Datumsfunktionen und ein paar SQLite-spezifische Features (Partial Indexes mit eigenwilligen Bedingungen, WITHOUT ROWID, STRICT Tables), für die es in MySQL keine direkten Entsprechungen gibt.
Andersherum – von MySQL zu SQLite – ist seltener, aber genauso möglich, meist für Offline-Analysen, eingebettete Kopien einer Datenteilmenge oder Testfixtures.
Der Punkt: Wenn du dich heute für SQLite entscheidest, bist du nicht festgenagelt. Das SQL, das du schreibst, lässt sich mitnehmen – und dein Verständnis erst recht.
Als Nächstes: SQLite vs PostgreSQL
MySQL ist der häufigste Vergleich, aber PostgreSQL ist die andere Datenbank, der SQLite oft gegenübergestellt wird – und die Unterschiede liegen dort wieder ganz woanders. Genau darum geht es auf der nächsten Seite.
Häufig gestellte Fragen
Was ist der wichtigste Unterschied zwischen SQLite und MySQL?
SQLite ist eine eingebettete Datenbank – im Grunde eine einzelne Datei, die deine Anwendung direkt liest und schreibt, ganz ohne Serverprozess. MySQL dagegen ist eine klassische Client-Server-Datenbank: Ein eigener mysqld-Prozess lauscht auf einem Port, und deine Anwendung redet über das Netzwerk mit ihm. Aus diesem einen architektonischen Unterschied ergeben sich praktisch alle weiteren Trade-offs.
Ist SQLite schneller als MySQL?
Wenn ein einzelner Prozess liest und kleinere Schreiboperationen macht, dann ja – SQLite spart sich den Netzwerk-Roundtrip und den Overhead zwischen Prozessen und ist dadurch oft schneller. Sobald aber viele Schreibvorgänge parallel laufen, gewinnt MySQL klar, denn SQLite serialisiert Schreibzugriffe auf Datenbankebene. Was passt, hängt also vom Workload ab und nicht von den Engines im luftleeren Raum.
Wann sollte ich SQLite statt MySQL nehmen?
SQLite passt super für eingebettete Anwendungen, Mobile, Desktop-Tools, CLI-Programme, lokale Caches, Tests und kleine bis mittlere Webseiten mit nur einem Application Server. Zu MySQL würde ich greifen, sobald mehrere App-Server auf eine gemeinsame Datenbank zugreifen, du feingranulare Benutzerrechte brauchst oder so viel parallel geschrieben wird, dass Row-Level-Locking wirklich einen Unterschied macht.
Kann ich später von SQLite zu MySQL migrieren?
Ja, und das ist ein ziemlich üblicher Weg. Bei CREATE TABLE, INSERT und SELECT überlappen sich die SQL-Dialekte stark, aber bei den Datentypen muss man Hand anlegen (INTEGER PRIMARY KEY wird zu INT AUTO_INCREMENT), genauso bei Datumsfunktionen und SQLite-Eigenheiten wie WITHOUT ROWID oder partiellen Unique-Indizes. Tools wie pgloader oder eigene Dump-Skripte nehmen dir den Großteil der Arbeit ab.