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.
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.
