Zum Inhalt springen

MySQL oder Postgres für Laravel: die echten Unterschiede

Eloquent verbirgt den größten Teil des Abstands zwischen beiden, und dann reist eine Handvoll Eigenschaften nicht mit. Welche das sind, und welche davon Sie nach einem Jahr merken.

4 Min. Lesezeit

Eloquent verbirgt den Unterschied gut genug, dass die meisten Teams aus Gewohnheit wählen und nie erfahren, was sie gewählt haben. Das ist meistens in Ordnung. Es hört an vier konkreten Stellen auf, in Ordnung zu sein, und alle vier kommen lange nach der Entscheidung.

Wo sie wirklich gleich sind

Alles, was die meisten Anwendungen tun. select, insert, Joins, Transaktionen, Indizes, Fremdschlüssel, der Query Builder, der Schema Builder, Migrationen, Factories und jeder Beziehungstyp in Eloquent. Ist die Anwendung CRUD über ein relationales Schema, spüren Sie lange keinen Unterschied.

Die ehrliche Rahmung ist also nicht "was ist besser", sondern: welche der vier Abweichungen unten erreicht Ihre Anwendung tatsächlich.

1. JSON, wo Postgres vorn liegt und es zählt

Beide speichern JSON. Nur eines indiziert beliebige Pfade darin gut.

$table->json('settings');

Auf Postgres wollen Sie jsonb statt json, und Laravels jsonb() gibt es Ihnen. Der Unterschied: jsonb wird geparst und binär abgelegt, sodass ein GIN-Index es abdecken kann - eine Abfrage wie diese nutzt also einen Index:

Order::where('meta->channel', 'marketplace')->get();

Auf MySQL bringt Sie eine generierte Spalte plus Index darauf für einen bekannten Pfad ans selbe Ziel, was in Ordnung ist, wenn Sie einen bekannten Pfad haben, und mühsam, wenn die Form wirklich dynamisch ist.

Speichert die Anwendung einen Einstellungsblock je Mandant, eine Nutzlast je Webhook oder irgendetwas, wonach Sie später filtern wollen, ohne heute zu wissen nach welchem Schlüssel - das ist das stärkste Einzelargument für Postgres in einer Laravel-Anwendung.

2. Groß- und Kleinschreibung, eine Verhaltensfalle

MySQLs Standardkollation ignoriert Groß- und Kleinschreibung. Postgres nicht.

User::where('email', 'Test@example.com')->first();

Das findet test@example.com auf MySQL und nichts auf Postgres. Jede gegen MySQL geschriebene Anwendung hat eine gewisse Anzahl Vergleiche, die nur wegen dieses Standards funktionieren, und niemand hat aufgeschrieben, welche.

Keines der beiden Verhalten ist falsch. Falsch ist, den Unterschied während einer Migration zu entdecken. Normalisieren Sie beim Schreiben - die Adresse in einem Mutator kleinschreiben, einen eindeutigen Index auf die normalisierte Spalte - und die Frage hört in beiden Engines auf zu zählen.

Dasselbe gilt für die Sortierung. ORDER BY name ordnet apfel und Apfel in beiden unterschiedlich ein, was in paginierten Listen als Datensätze auftaucht, die auf zwei Seiten oder auf keiner erscheinen.

3. Constraints und Typen, die Postgres hat und MySQL nicht

Check Constraints, die wirklich prüfen. Eine Statusspalte auf vier Werte beschränkt, von der Datenbank durchgesetzt statt von einem Form Request, den ein eingereihter Job umgehen kann.

Partielle Indizes. Ein Index nur über die Zeilen, die zählen - WHERE deleted_at IS NULL auf einer Tabelle mit Soft Delete, oder nur die aktiven Abonnements. Auf einer großen Tabelle mit kleiner heißer Teilmenge ist das ein großer Gewinn, und MySQL hat kein Gegenstück.

Echte Array- und Bereichstypen sowie Erweiterungen. Wenn irgendetwas geografisch ist, ist PostGIS der Grund, warum die Entscheidung bereits gefallen ist.

INSERT ... RETURNING, was Laravel bereitstellt und was bedeutet, dass ein Insert, der die erzeugte Zeile zurückbraucht, ein Roundtrip statt zwei ist.

4. Die Betriebsunterschiede, die einen nachts wecken

Schemaänderungen. Beide können sperren. Postgres fügt eine nullable Spalte sofort hinzu und baut einen Index CONCURRENTLY - was Laravel nicht ausgibt, Sie schreiben es also von Hand, und es läuft nicht in einer Transaktion. Aktuelles MySQL hat sofortige Spaltenerweiterung für viele Fälle und Online DDL für viele mehr. Keines ist auf einer großen Tabelle per Standard sicher, und der Fehlermodus ist identisch.

Replikation und Verbindungen. Postgres-Verbindungen sind teurer, weshalb eine Laravel-Anwendung mit großer Worker-Flotte früher an ein Verbindungslimit stößt und ein Pooler früher davor auftaucht. MySQL verträgt eine höhere rohe Verbindungszahl. Das hängt direkt damit zusammen, wie viele Queue-Worker Sie betreiben.

Volltextsuche. Postgres hat brauchbare eingebaute Volltextsuche mit Ranking. Die von MySQL ist schwächer. Beide sind ein Zwischenschritt vor einer echten Suchmaschine, aber der Zwischenschritt trägt auf Postgres länger.

Wie man tatsächlich wählt

Nehmen Sie Postgres, wenn das Datenmodell JSON enthält, das Sie abfragen werden, oder Constraints, die Sie durchgesetzt statt geglaubt haben wollen, oder irgendetwas Geografisches, oder Auswertungen, die bald Fensterfunktionen und CTEs wollen.

Nehmen Sie MySQL, wenn Ihr Team und Ihr Hosting es bereits betreiben und die Anwendung geradlinige relationale Arbeit ist. Vertrautheit bei den Menschen, die um drei Uhr nachts geweckt werden, ist ein echter technischer Faktor, kein Zugeständnis.

Und was Sie auch wählen, legen Sie es überall fest. Die teuerste Version dieser Entscheidung ist ein Team, das auf SQLite entwickelt, auf MySQL testet und Postgres in Produktion betreibt und die Unterschiede einen Vorfall nach dem anderen entdeckt. Ihre lokale Umgebung, Ihr CI und Ihre Produktionsdatenbank sollten dieselbe Engine in derselben Hauptversion sein - aus Gründen, die auch in der Testsuite auftauchen.

Verwandte Fragen

Bevorzugt Laravel eines von beiden?
Nicht wirklich. Beide sind im Framework erstklassig unterstützt, beide werden vom Query Builder und vom Schema Builder abgedeckt, und gegen beide wird Laravel getestet. Wo das Framework sich neigt, sind Standardwerte statt Unterstützung - und ein Standard ist keine Empfehlung für Ihre Last.
Können wir später wechseln?
Schema und Migrationen ziehen mit überschaubarem Aufwand um. Nicht günstig umzieht alles, was eine Eigenschaft nutzte, die nur einer von beiden hat, und alles, wo Ihr Code sich auf einen Verhaltensunterschied verließ, ohne ihn zu benennen - die Sortierung bei gemischter Groß- und Kleinschreibung ist der Klassiker. Planen Sie die Datenmigration und die Auswertungsabfragen ein, nicht das ORM.
Was ist schneller?
Für die Abfragen einer typischen Geschäftsanwendung ist der Unterschied weit kleiner als der Unterschied, den ein fehlender Index macht. Beide tragen Sie deutlich über den Punkt hinaus, an dem Ihr Schema der Engpass ist. Nach Benchmarks zu wählen heißt, die falsche Variable zu optimieren.
Und MariaDB?
Nahe genug an MySQL für fast alles in Laravel, und in Teilen abgewichen - JSON-Behandlung und manche neuere Syntax darunter. Behandeln Sie es als eigenes Ziel statt Gleichstand anzunehmen, und legen Sie fest, wogegen Ihr CI läuft.

← Zurück zu allen Artikeln

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