Zum Inhalt springen

SQLite ist Laravels Standard. Wann reicht das?

Der Standard hat sich geändert, und viele Anwendungen gingen damit in Produktion, ohne dass jemand es entschieden hätte. Die Fälle, in denen das richtig ist, sind enger als gedacht.

4 Min. Lesezeit

Laravels Standarddatenbank ist SQLite, und Standards sind mächtig. Eine nennenswerte Zahl von Anwendungen erreicht die Produktion heute darauf, weil niemand die Zeile geändert hat, nicht weil jemand entschieden hätte, dass es passt.

Manchmal passt es. Hier verläuft die Linie tatsächlich.

Was wirklich anders ist

Nicht das SQL. Nicht Eloquent, das sich gleich verhält. Eine Sache: SQLite ist eine Datei, die Ihr Prozess öffnet, kein Server, zu dem er sich verbindet.

Alles folgt daraus. Es gibt kein Verbindungslimit, weil es keine Verbindungen gibt. Es gibt keine Netzwerklatenz, weil es kein Netzwerk gibt. Und Schreibzugriffe werden über jeden Prozess serialisiert, der die Datei anfasst, weil eine Datei keinen Planer hat, der zwischen Clients vermittelt.

Schalten Sie WAL ein, bevor Sie sonst etwas tun. Ohne WAL blockiert ein Leser einen Schreiber und ein Schreiber die Leser, und das ist die Konfiguration, die die meisten Leute messen, ohne es zu wissen:

// eine Migration, oder ein Service Provider
DB::statement('PRAGMA journal_mode = WAL');
DB::statement('PRAGMA busy_timeout = 5000');
DB::statement('PRAGMA foreign_keys = ON');

Diese drei sind nahezu Pflicht. WAL lässt Leser während eines Schreibvorgangs weiterarbeiten. Der Busy-Timeout verwandelt einen sofortigen database is locked-Fehler in eine kurze Wartezeit, was fast immer gewollt war. Und Fremdschlüssel sind in SQLite standardmäßig aus, was Leute überrascht, die constrained() in eine Migration geschrieben und angenommen haben, es werde durchgesetzt.

Wo es die richtige Antwort ist

Ein internes Werkzeug. Zwanzig Personen, überwiegend lesend. Die betriebliche Ersparnis ist real: kein Datenbankserver zu patchen, zu sichern, abzusichern oder zu bezahlen, und ein Backup ist eine Dateikopie.

Eine Ein-Server-Anwendung mit moderaten Schreibzugriffen. Eine Inhaltsseite, eine Buchungsseite, ein kleines SaaS im ersten Jahr. SQLite auf lokaler Platte ist für einen einzelnen Leser schneller als Postgres über Netzwerk, weil kein Socket überquert wird.

Tests. Eine In-Memory-SQLite-Datenbank macht eine Suite schnell, mit dem Vorbehalt unten.

Alles Eingebettete oder am Rand Ausgelieferte, wo ein Datenbankserver überhaupt nicht zur Verfügung steht.

Wo es das nicht ist

Mehrere Anwendungsserver. Das ist die harte Grenze. Zwei Webserver können eine SQLite-Datei über ein Netzwerkdateisystem nicht sicher teilen. Wenn Sie je horizontal skalieren, muss diese Entscheidung erneut getroffen werden, und sie später zu treffen heißt Migration unter Zeitdruck.

Schreiblastige Arbeit. Alles, was jede Anfrage protokolliert, Ereignisse aufnimmt oder eine Queue in der Datenbank verarbeitet. Schreibzugriffe serialisieren; das ist der Entwurf, kein Tuning-Problem.

Mehr als ein, zwei Queue-Worker. Worker, die eine Jobs-Tabelle abfragen, sind gleichzeitige Schreiber. Nehmen Sie Redis für die Queue und SQLite für die Anwendung, oder betreiben Sie einen Worker und akzeptieren Sie den Durchsatz.

Alles, was Point-in-Time-Recovery braucht, Replikation oder eine Lese-Replik. Es gibt Werkzeuge, die Replikation auf SQLite aufsetzen, und die sind eine Abhängigkeit und eine Entscheidung, kein Standard.

Die Testfalle

Die häufigste SQLite-Entscheidung in einer Laravel-Codebasis ist nicht die in Produktion. Es ist :memory: in phpunit.xml, wegen der Geschwindigkeit gewählt, gegen eine Anwendung, die MySQL oder Postgres betreibt.

Diese Suite kann nicht fangen:

  • Eine Constraint-Verletzung, die die echte Engine durchsetzt und SQLite nicht.
  • Einen Kollationsunterschied, also die Groß-/Kleinschreibungsfalle mit anderem Hut.
  • Eine Migration, die eine große Tabelle sperrt, weil es weder Sperre noch Tabelle gibt.
  • Alles mit einem JSON-Operator, einer Fensterfunktion oder einem Typ, den die echte Engine hat und SQLite nicht.

Für eine unit-lastige Suite ist das ein vernünftiger Tausch und als einziges Bollwerk gegen einen Schemafehler ein schlechter. Lassen Sie die schnelle Suite auf SQLite laufen, wenn Sie mögen; lassen Sie die Suite, die ein Deployment freigibt, gegen die Engine laufen, auf die Sie deployen.

Ehrlich entscheiden

Stellen Sie eine Frage: wird diese Anwendung je auf mehr als einem Server laufen?

Ist die Antwort nein und wissen Sie warum - sie ist intern, sie hat eine Obergrenze, sie ist tatsächlich klein - dann ist SQLite kein Kompromiss. Es ist weniger Infrastruktur, die Ihnen gehört, und weniger Infrastruktur zu besitzen ist ein echter Vorteil, der zu leicht abgetan wird.

Ist die Antwort ja, oder "wahrscheinlich nicht, aber wer weiß", beginnen Sie auf der Engine, auf der Sie enden würden. Eine laufende Anwendung zu migrieren ist Arbeit, die Sie ganz vermeiden, indem Sie in Woche eins zehn Minuten darauf verwenden - dasselbe Argument wie bei Geld und Zeit, und es gilt aus demselben Grund.

Verwandte Fragen

Ist SQLite eine richtige Datenbank?
Vollständig, und es ist vermutlich die am häufigsten eingesetzte der Welt. Die Frage ist nie, ob es ernsthafte Software ist - sondern ob sein Nebenläufigkeitsmodell zu Ihrem Schreibmuster passt, denn das ist die eine Dimension, in der es sich von einer Client-Server-Datenbank unterscheidet und die Sie nicht wegkonfigurieren können.
Was bricht zuerst bei Wachstum?
Gleichzeitige Schreibzugriffe. SQLite serialisiert sie, ein zweiter Schreiber wartet also. Mit WAL blockieren Leser nicht, und ein schreiblastiger Endpunkt unter echter Last steht trotzdem hinter sich selbst an - und das Symptom ist ein Sperr-Timeout statt einer langsamen Abfrage, was die Suche in die falsche Richtung schickt.
Können wir es mit Queue-Workern betreiben?
Vorsichtig, und meist nicht mit dem Datenbank-Queue-Treiber. Mehrere Worker, die eine Jobs-Tabelle abfragen, sind mehrere gleichzeitige Schreiber gegen eine Datenbank, die für einen nach dem anderen entworfen ist. Nehmen Sie Redis für die Queue, oder akzeptieren Sie genau einen Worker.
Wie kommen wir später davon weg?
Schema und Eloquent-Code ziehen fast unverändert um; die Daten müssen exportiert und die lose Typisierung geprüft werden. SQLite akzeptiert eine Zeichenkette in einer Integer-Spalte, ein Dump kann also Werte enthalten, die das Ziel ablehnt. Prüfen Sie vor der Migration, nicht währenddessen.

← Zurück zu allen Artikeln

Anrufen+1 848 272 7583WhatsApp+90 850 308 5436E-Mailinfo@codefacture.comKontaktseite