Zum Inhalt springen

Individualsoftware-Entwicklung

Individualsoftware mit Next.js und PostgreSQL

Was die Wahl von PostgreSQL in einem Next.js-Bau konkret ändert - die Garantien, die es erzwingt, die Suche, für die kein Dienst mehr nötig ist, und die Falle, in die jedes Team einmal läuft.

PostgreSQL für einen individuellen Bau zu wählen hat konkrete Folgen, und die gehören ausgesprochen statt vorausgesetzt. Es ist bei diesen Projekten der Standard, keine Regel, und der Grund ist, dass es Arbeit aus der Anwendung an eine Stelle verschiebt, an der sie nicht umgangen werden kann.

Garantien, die die Anwendung nicht vergessen kann

Das stärkste Argument für eine relationale Datenbank in Individualsoftware hat nichts mit Geschwindigkeit zu tun.

Eine Anwendung wird über Jahre von mehreren Leuten geschrieben, und nicht alle kennen die Regeln. Eine im Anwendungscode erzwungene Garantie gilt für die Pfade, an die jemand gedacht hat - und nicht für das Importskript, das Console-Command, den Cron-Job oder die Admin-Maske, die im nächsten Frühjahr dazukommt.

Eine in der Datenbank erzwungene Garantie gilt für alle. Ein Fremdschlüssel bedeutet, dass ein Auftrag keinen Kunden referenzieren kann, der nicht existiert. Ein Unique-Constraint bedeutet, dass zwei gleichzeitige Anfragen nicht beide denselben Datensatz anlegen können - was kein Prüfen-dann-Einfügen im Code erreicht. Ein Check-Constraint bedeutet, dass eine Menge nicht negativ sein kann, in der Zeile und nicht bloß im Formular.

PostgreSQL geht dabei weiter als die meisten, und zwar auf eine Weise, die für echte Anwendungen zählt. Ein Exclusion-Constraint kann eine Buchung abweisen, deren Zeitraum sich mit einer bestehenden für dieselbe Ressource überschneidet - eine Race Condition, die im Anwendungscode wirklich schwer und hier trivial zu schließen ist. Partielle Indexe indexieren nur die Zeilen, die zählen, sodass eine Abfrage über aktive Datensätze nicht für das Archiv mitbezahlt.

Was das aus dem Code entfernt

Jede dieser Garantien ist Validierungscode, den Sie nicht schreiben, nicht testen und nicht erinnern müssen, wenn eine siebte Art hinzukommt, einen Datensatz zu erzeugen.

Es ist außerdem der Unterschied zwischen einem unmöglichen und einem unwahrscheinlichen Fehler. In einem System, das Geld, Bestand oder Termine verwaltet, ist das der ganze Punkt.

JSONB, und wo die Linie liegt

Manche Daten widersetzen sich einem Schema wirklich. Die Nutzlast eines Webhooks von einem Dritten. Ein Formular, dessen Felder der Kunde konfiguriert. Einstellungen pro Mandant, die sich je Mandant unterscheiden.

PostgreSQL behandelt das ehrlich: JSONB wird effizient gespeichert, mit echten Operatoren abgefragt und mit GIN indexiert, also sind unstrukturierte Daten eine erstklassige Wahl und keine Notlösung.

Die Linie, die man halten sollte: alles, wonach Sie filtern, sortieren, berichten, joinen oder was Sie einschränken, bekommt eine Spalte. Das Fehlermuster ist bekannt und langsam - eine JSON-Spalte wird zum Ort, an den neue Felder wandern, weil eine Migration schwer wirkte, und zwei Jahre später kann niemand eine Frage zu den Daten beantworten, ohne Anwendungscode zu lesen.

Suche, ohne ein zweites System

Ein großer Teil der Anwendungen nimmt einen Suchdienst, eine Synchronisation und eine betriebliche Abhängigkeit in Kauf, um etwas zu tun, was die Datenbank schon kann.

Volltextsuche in PostgreSQL hat Stemming, Ranking und Konfigurationen für mehrere Sprachen, und sie indexiert gut. Bei einigen Hunderttausend Datensätzen ist sie schnell, und sie hat den erheblichen Vorteil, dass Suchergebnisse nicht veralten können, weil es nichts zu synchronisieren gibt.

Wo sie ausgeht, ist real und gehört benannt - Tippfehlertoleranz, großflächiges Relevanz-Tuning, facettierte Suche über Millionen Dokumente. Diesen Punkt zu erreichen ist eine Messung, keine Vorhersage, und später dort anzukommen kostet weit weniger, als ab Woche eins einen Suchcluster für einen Datenbestand zu betreiben, der ihn nie gebraucht hätte.

Die eine Falle, und wie sie behandelt wird

Jedes Team begegnet ihr einmal. Eine Next.js-Anwendung auf einer serverlosen Laufzeit öffnet pro Instanz eine Datenbankverbindung, und PostgreSQL akzeptiert eine feste Anzahl. Unter Verkehr wird die Anwendung nicht langsamer - sie beginnt Verbindungen abzulehnen, was wie ein Datenbankausfall liest und ein Konfigurationsfehler ist.

Die Antwort ist ein Connection Pooler zwischen Anwendung und Datenbank, und was dabei erwischt: Pooling im Transaktionsmodus ist mit Prepared Statements unvereinbar, solange der Client nicht dafür konfiguriert ist. Connection Pooling in einer serverlosen Laufzeit ist die vollständige Erklärung.

Bei diesen Bauten wird das in Woche eins entschieden, und das ist der Unterschied zwischen einer bekannten Rahmenbedingung und einem Vorfall.

Wie ein Projekt abläuft

In Phasen, jede vor Beginn schriftlich fixiert und jede endet mit etwas Ausgelieferten, das Sie benutzen können. Die erste Phase nimmt einen Ablauf von Anfang bis Ende statt des Umrisses mehrerer, denn das entscheidet das Schema an echten Daten.

Die Datenbankentscheidungen fallen in dieser ersten Phase und nicht danach. Welche Constraints wo erzwungen werden, was eine Spalte ist und was JSONB, wie Migrationen gegen eine Tabelle laufen, die später groß wird, und wie das Pooling aussieht. Keine davon ist früh teuer, und alle sind teuer zu ändern, wenn Produktionsdaten dahinterliegen.

Was Sie bekommen

Eine ausgelieferte Anwendung am Ende jeder Phase, das Repository mit intakter Historie, und das Schema als Migrationen statt als Ist-Zustand - damit die Datenbank eine Historie hat, die sich abspielen und reviewen lässt.

Dazu: eine schriftliche Notiz zum Datenmodell und warum es so geformt ist, die Indexe und wofür jeder einzelne da ist, die Pooling-Konfiguration, und die Constraints mit je einer Zeile dazu, was sie verhindern. Letzteres ist das Dokument, zu dem Leute wirklich zurückkehren, denn ein Constraint, den niemand versteht, ist ein Constraint, den irgendwann jemand entfernt.

Wann PostgreSQL nicht die Antwort ist

Wenn die Anwendung eine dünne Schicht über der API eines Dritten ist und fast keinen eigenen Zustand hält, betreiben Sie eine Komponente ohne Grund - und ein einfacherer Speicher ist die bessere Antwort.

Wenn die Last wirklich ein Cache oder eine Queue ist, sollte es ein Cache oder eine Queue sein. PostgreSQL kann beides passabel und ist für keines von beiden gedacht.

Und wenn die Daten hochvolumige Messwerte sind, die nur angehängt werden - Sensordaten, Telemetrie im großen Stil -, nimmt eine relationale Tabelle davon überraschend viel, aber es gibt einen Punkt, jenseits dessen ein spezialisierter Speicher gewinnt. Dieser Punkt sollte durch Messen festgestellt werden und nicht durch die Annahme, er sei schon erreicht.

Umfang und Konditionen

Zusammenarbeit
Fester Umfang, schriftlich vereinbart, bevor die Arbeit beginnt. Kein Tagessatz gegen ein offenes Backlog.
Preis und Dauer
Beides wird je Projekt festgelegt, sobald der Umfang steht. Gemeinsam angeboten, bevor etwas gebaut wird.
Was wir von Ihnen brauchen
Eine Person, die entscheiden darf, und Zugang zu Ihrem Repository und Ticketsystem.
Nicht enthalten
Alles außerhalb des vereinbarten Umfangs. Es wird ein eigener Umfang statt eines Änderungsauftrags.
Kosten Dritter
Hosting, Lizenzen, API-Gebühren und SaaS-Abonnements schließen und zahlen Sie selbst.
Rechnungsstellung
Codefacture Yazılım A.Ş., Türkiye. EUR, USD oder GBP per Überweisung, ohne türkische Umsatzsteuer auf exportierte Leistungen.

Häufige Fragen

Warum PostgreSQL und nicht eine verwaltete Dokumentendatenbank?
Weil die meiste Individualsoftware Beziehungen hat, und eine Datenbank, die sie erzwingt, erledigt Arbeit, die Ihre Anwendung sonst schlecht erledigen müsste. Fremdschlüssel, Unique- und Check-Constraints sind Garantien, die gelten, egal welcher Codepfad die Zeile geschrieben hat - auch das in Eile geschriebene Console-Command und der Import, den niemand reviewt hat. Ein Dokumentenspeicher verlangt von der Anwendung, diese Disziplin dauerhaft zu halten, und Anwendungen überleben die Leute, die die Disziplin verstanden haben.
Was ist dieses Verbindungsproblem, vor dem alle warnen?
Jede serverlose Instanz, die eine Anfrage bearbeitet, öffnet ihre eigene Datenbankverbindung, und PostgreSQL akzeptiert nur eine feste Zahl davon. Unter Last wird die Anwendung nicht langsamer, sie beginnt Verbindungen abzulehnen - das sieht wie ein Datenbankausfall aus und ist ein Konfigurationsfehler. Die Antwort ist ein Pooler vor der Datenbank, und was Teams dabei erwischt - Pooling im Transaktionsmodus verträgt sich nicht mit Prepared Statements, der ORM muss also dafür konfiguriert sein. Ein gelöstes Problem, das in Produktion zu entdecken ausgesprochen unangenehm ist.
Können wir Daten als JSON halten statt Spalten dafür zu entwerfen?
Ja, und PostgreSQL ist die Datenbank, in der das eine vernünftige Entscheidung ist und kein Rückzug. JSONB ist indexierbar, also kann ein Feld, das Sie wirklich nicht modellieren können - die Nutzlast eines Dritten, ein Formular, dessen Form der Kunde bestimmt, Einstellungen pro Mandant - dort liegen und trotzdem abgefragt werden. Die Linie, die man halten sollte: alles, wonach Sie filtern, sortieren, berichten oder joinen, bekommt eine Spalte. Eine JSON-Spalte, die zum Ort für neue Felder wird, ist der Weg, auf dem ein Schema aufhört, ein Schema zu sein.
Heißt PostgreSQL, dass wir keinen Suchdienst brauchen?
Für sehr viele Anwendungen ja, und das sind ein Dienst und eine Synchronisationsstrecke, die Sie nie betreiben müssen. Volltextsuche mit Ranking, Stemming und mehreren Sprachen ist eingebaut, und bei einigen Hunderttausend Datensätzen ist sie schnell genug, dass die Alternative verfrüht wäre. Wirklich aus geht sie bei Tippfehlertoleranz, großflächigem Relevanz-Tuning und facettierter Suche über Millionen Dokumente - und dieser Schluss sollte aus einer Messung kommen und nicht aus einer Annahme.
Ist das ein anderes Projekt als Ihre übrige Individualsoftware?
Nein - es ist die gleiche Arbeit mit benannter Datenschicht, und genau deshalb gibt es diese Seite separat. Wenn Sie gezielt ein Team für Next.js und PostgreSQL suchen, steht hier, was diese Wahl ändert. Zuschnitt, Phasen und Ergebnisse sind dieselben wie auf der Seite zur Individualsoftware.
Anrufen+1 848 272 7583WhatsApp+90 850 308 5436E-Mailinfo@codefacture.comKontaktseite