Skip to main content
backend30. November 202512 Min. Lesezeit

Die richtige Datenbank wählen: Relational vs NoSQL für echte Projekte

Ein praxisnahes Entscheidungs-Framework für die Wahl zwischen PostgreSQL, MongoDB, Firebase, Redis und anderen Datenbanken basierend auf Ihren tatsächlichen Anforderungen.

databasepostgresqlmongodb
Die richtige Datenbank wählen: Relational vs NoSQL für echte Projekte

„Es kommt darauf an" ist die ehrliche Antwort auf jede Datenbankfrage, aber sie ist auch nutzlos. Wenn Sie ein Projekt starten und eine Datenbank wählen müssen, brauchen Sie etwas Konkreteres als eine Liste von Kompromissen. Sie brauchen ein Entscheidungs-Framework, das Ihre tatsächlichen Anforderungen berücksichtigt — Datenstruktur, Abfragemuster, Team-Expertise, Skalierungserwartungen und operative Komplexität.

Ich habe PostgreSQL, MongoDB, Firebase/Firestore, Redis und SQLite in verschiedenen Produktionsprojekten eingesetzt. Jede Wahl war in ihrem Kontext richtig, und einige waren falsch und mussten migriert werden. Die Muster hinter diesen Entscheidungen sind nützlicher als jeder Benchmark-Vergleich.

Das Entscheidungs-Framework

Bevor Sie sich einzelne Datenbanken ansehen, beantworten Sie diese fünf Fragen über Ihr Projekt:

1. Welche Form haben Ihre Daten?

Das ist keine Frage von „relational vs. Dokument." Es geht darum, wie Ihre Datenentitäten zueinander in Beziehung stehen.

Stark relational: Benutzer haben Bestellungen, Bestellungen haben Positionen, Positionen gehören zu Kategorien, Kategorien haben Hierarchien. Wenn Sie Ihr Datenmodell zeichnen und es wie ein Graph mit vielen Verbindungen aussieht, brauchen Sie starke relationale Fähigkeiten.

Dokumentenorientiert: Jede Entität ist relativ in sich geschlossen. Ein Blogbeitrag enthält seinen Titel, Text, Tags und Autoreninformationen. Sie müssen selten über Entitätstypen hinweg joinen.

Key-Value: Sie müssen Daten nach Schlüssel speichern und abrufen. Session-Daten, Konfiguration, Feature Flags.

Zeitreihen: Events, Metriken, Logs. Schreibintensiv, nur anhängend, nach Zeitbereich abgefragt.

2. Was sind Ihre Abfragemuster?

Bekannte Abfragen: Sie wissen genau, welche Abfragen die Anwendung ausführen wird. E-Commerce: „Bestellungen des Nutzers abrufen", „Produkte nach Kategorie finden", „Gesamtumsatz dieses Monats berechnen." Bekannte Abfragen begünstigen relationale Datenbanken, wo Sie mit Indizes und Abfrageplänen optimieren können.

Ad-hoc-Abfragen: Nutzer können auf unvorhersehbare Weise suchen, filtern und aggregieren. Analytics-Dashboards, Suchfunktionen, Berichtswerkzeuge. Diese begünstigen flexible Abfrage-Engines.

Einfache Lookups: Die meisten Lesevorgänge sind „Dokument nach ID abrufen." Dokumentdatenbanken und Key-Value-Stores glänzen hier.

3. Was ist Ihre Konsistenzanforderung?

Starke Konsistenz: Banking, Inventar, alles wo das Lesen veralteter Daten echte Probleme verursacht. Relationale Datenbanken mit ACID-Transaktionen sind die sichere Wahl.

Eventual Consistency: Social Feeds, Analytics, Caching. Sie können es tolerieren, leicht veraltete Daten zu lesen, im Austausch für Performance und Verfügbarkeit.

4. Wie sieht Ihre Skalierungsperspektive aus?

Vertikale Skalierung reicht: Die meisten Anwendungen. Wenn Ihre Datenbank auf einen einzelnen Server passt und Raum zum Wachsen hat, funktioniert jede Datenbank. PostgreSQL auf einem modernen Server bewältigt Millionen von Zeilen ohne Probleme.

Horizontale Skalierung erforderlich: Sie müssen Daten über mehrere Maschinen verteilen. Das ist seltener, als die meisten Entwickler denken, aber wenn Sie es brauchen, ist Ihre Datenbankwahl eingeschränkt.

5. Was weiß Ihr Team?

Dieser Faktor wird unterschätzt. Ein Team von PostgreSQL-Experten wird mit PostgreSQL produktiver sein, selbst wenn MongoDB theoretisch besser zum Datenmodell passt. Die Kosten des Erlernens einer neuen Datenbank — unbekannte Fehler debuggen, operative Best Practices lernen, Performance-Charakteristiken verstehen — sind real und erheblich.

PostgreSQL: Die Standardwahl

Wenn Sie unsicher sind, wählen Sie PostgreSQL. Das ist keine kontroverse Meinung unter Backend-Ingenieuren — es ist der Konsens. PostgreSQL beherrscht relationale Daten, JSON-Dokumente, Volltextsuche, räumliche Abfragen und Zeitreihendaten. Es ist nicht das Beste in einem einzelnen dieser Bereiche, aber gut genug in allen, um als einzelne Datenbank für die meisten Anwendungen zu dienen.

Stärken

ACID-Transaktionen. Wenn Sie mehrere Tabellen atomar aktualisieren müssen — Inventar abziehen und eine Bestellung erstellen, Geld zwischen Konten transferieren — garantiert PostgreSQL Korrektheit.

Reiche Abfragefähigkeiten. Window Functions, CTEs (Common Table Expressions), rekursive Abfragen, Lateral Joins. SQL ist nicht nur SELECT * FROM — es ist eine mächtige Abfragesprache, die komplexe Analysen ausdrücken kann, ohne Daten in eine Anwendungsschicht verschieben zu müssen.

-- Find each user's most recent order with running total
WITH ranked_orders AS (
  SELECT
    user_id,
    order_id,
    total,
    created_at,
    ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY created_at DESC) as rn,
    SUM(total) OVER (PARTITION BY user_id ORDER BY created_at) as running_total
  FROM orders
)
SELECT * FROM ranked_orders WHERE rn = 1;

JSONB-Spalten. Wenn ein Teil Ihrer Daten wirklich schemalos ist — Benutzereinstellungen, dynamische Formularantworten, Webhook-Payloads von Drittanbietern — können Sie sie als JSONB speichern und mit voller Index-Unterstützung abfragen.

-- Store and query semi-structured data
CREATE TABLE products (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL,
  attributes JSONB DEFAULT '{}'
);

-- Index a specific JSON path
CREATE INDEX idx_products_color ON products USING GIN ((attributes->'color'));

-- Query JSON data
SELECT name FROM products
WHERE attributes->>'color' = 'blue'
AND (attributes->>'weight')::numeric < 10;

Extensions-Ökosystem. PostGIS für Geodaten, pg_trgm für unscharfe Textsuche, TimescaleDB für Zeitreihen, pgvector für KI-Embeddings. Das Extension-Modell bedeutet, dass PostgreSQL sich an spezialisierte Workloads anpassen kann, ohne Ihre primäre Datenbank zu ersetzen.

Wann PostgreSQL nicht die richtige Wahl ist

  • Massiver Schreibdurchsatz mit horizontaler Skalierung. PostgreSQL skaliert vertikal gut (größere Maschine), aber horizontales Sharding ist komplex. Wenn Sie Millionen von Events pro Sekunde über Dutzende Maschinen schreiben müssen, erwägen Sie zweckgebaute Lösungen.
  • Schnelles Prototyping, bei dem sich das Schema täglich ändert. In den frühesten Phasen eines Startups, wenn sich das Datenmodell jede Woche fundamental ändert, kann der Migrations-Overhead Sie im Vergleich zu schemalosen Optionen verlangsamen.
  • Wenn Ihr Team keinerlei SQL-Erfahrung hat und der Projektzeitraum kein Lernen erlaubt. Das ist selten, kommt aber vor.

MongoDB: Wenn Dokumente Sinn ergeben

MongoDB bekommt mehr Kritik als es verdient. Das frühe Marketing („schemalos! web scale!") schuf unrealistische Erwartungen, und viele Entwickler nutzten es für Anwendungsfälle, bei denen PostgreSQL besser gewesen wäre. Aber es gibt echte Szenarien, in denen MongoDB die richtige Wahl ist.

Wann MongoDB gewinnt

Content-Management-Systeme. Jedes Inhaltsstück hat eine andere Struktur — Artikel haben andere Felder als Videos, die andere Felder als Podcasts haben. In MongoDB sind das alles Dokumente in derselben Collection mit verschiedenen Formen. In PostgreSQL erstellen Sie entweder eine breite Tabelle mit vielen nullable Spalten, nutzen JSON-Spalten (womit Sie MongoDBs Paradigma in PostgreSQL verwenden) oder erstellen eine Tabelle pro Typ mit komplexen Joins.

Event Sourcing und Logging. Hoher Schreibdurchsatz mit Dokumenten, die überwiegend geschrieben und gelesen, selten aktualisiert und nie gejoined werden.

Eingebettete Dokumente reduzieren Joins. Wenn eine Bestellung immer ihre Positionen braucht und Positionen nie ohne ihre Bestellung abgerufen werden, bedeutet das Einbetten der Positionen im Bestelldokument, dass Ihre häufigste Abfrage ein einzelner Dokument-Lookup statt eines Joins über zwei Tabellen ist.

// MongoDB document with embedded sub-documents
{
  _id: ObjectId("..."),
  customer: {
    name: "John Doe",
    email: "john@example.com"
  },
  items: [
    { product: "Widget", quantity: 2, price: 9.99 },
    { product: "Gadget", quantity: 1, price: 24.99 }
  ],
  total: 44.97,
  status: "shipped",
  createdAt: ISODate("2026-03-01T10:00:00Z")
}

Horizontale Skalierung ist ein First-Class-Feature. MongoDBs Sharding ist eingebaut und gut dokumentiert. Wenn Sie wirklich Daten über viele Knoten verteilen müssen (Hunderte Millionen Dokumente mit hohem Durchsatz), bewältigt MongoDB das eleganter als PostgreSQL.

Wann MongoDB falsch ist

  • Stark relationale Daten. Wenn Sie in jeder Abfrage $lookup-Aggregationen (MongoDBs Version von Joins) schreiben, haben Sie die falsche Datenbank gewählt.
  • Wenn Sie häufig Transaktionen über Collections hinweg brauchen. MongoDB unterstützt Multi-Dokument-Transaktionen, aber sie fügen Latenz und Komplexität hinzu. Wenn Ihre Kernoperationen Collection-übergreifende Atomizität erfordern, ist PostgreSQL-Transaktionsmodell natürlicher.
  • Wenn Sie tatsächlich ein Schema brauchen. „Schemalos" klingt befreiend, bis Sie erkennen, dass jedes Stück Code, das aus der Datenbank liest, implizit ein Schema ist. Ohne datenbankerzwungenes Schema verschieben Sie die Validierung in die Anwendungsschicht, wo sie leichter falsch zu machen und schwerer konsistent durchzusetzen ist.

Firebase und Firestore: Schnelle Entwicklung

Firebase Realtime Database und Firestore bedienen eine spezifische Nische: Anwendungen, bei denen Entwicklungsgeschwindigkeit wichtiger ist als Datenmodellierungs-Reinheit, und bei denen das Backend primär eine Datenpersistenz- und Synchronisationsschicht ist statt einer komplexen Geschäftslogik-Engine.

Wann Firebase glänzt

Mobile-First-Apps mit Echtzeit-Synchronisation. Firebases SDKs übernehmen Offline-Caching, Echtzeit-Listener und Konfliktlösung standardmäßig. Das von Grund auf mit PostgreSQL zu bauen erfordert eine WebSocket-Schicht, eine Caching-Strategie und erheblichen benutzerdefinierten Code.

Kleine Teams ohne Backend-Ingenieure. Firebase eliminiert die Notwendigkeit, einen Datenbankserver zu verwalten, eine API-Schicht zu bauen, Authentifizierung zu implementieren und Dateispeicher zu handhaben. Für ein Zwei-Personen-Team, das ein MVP baut, kann diese Reduktion des operativen Overheads den Unterschied zwischen Ausliefern und Nicht-Ausliefern ausmachen.

Prototyping und Validierung. Wenn Sie eine Idee innerhalb von zwei Wochen mit echten Nutzern testen müssen, lässt Firebase Sie sich vollständig auf die Client-Anwendung konzentrieren. Wenn sich die Idee bewährt, können Sie später zu einem traditionelleren Backend migrieren.

Firebases Grenzen

Abfragebeschränkungen in Firestore. Sie können nicht auf nicht-indizierte Felder abfragen. Sie können keine Ungleichheitsfilter auf mehrere Felder anwenden. Sie können keine Volltextsuche durchführen. Diese Einschränkungen zwingen Sie, aggressiv zu denormalisieren und manchmal Daten über Collections hinweg zu duplizieren.

// Firestore: You CAN'T do this
db.collection('products')
  .where('price', '>', 10)
  .where('rating', '>', 4)
  .orderBy('name')  // Error: needs composite index on price + rating + name

// Firestore: You CAN do this (with a composite index)
db.collection('products')
  .where('price', '>', 10)
  .where('rating', '>', 4)
  .orderBy('price')  // Must order by a field used in inequality

Anbieter-Lock-in. Ihr Datenmodell, Ihre Sicherheitsregeln und Abfragemuster sind alle Firebase-spezifisch. Die Migration weg von Firebase ist ein Neuschrieb, keine Migration.

Kostenunberechenbarkeit. Firebase rechnet pro Dokumentenlese/-schreibvorgang ab. Eine schlecht optimierte Abfrage oder ein Echtzeit-Listener auf einer großen Collection kann überraschende Rechnungen erzeugen. Ich habe Projekte gesehen, bei denen ein einziger falsch konfigurierter Listener mehr kostete als ein dedizierter PostgreSQL-Server für ein ganzes Jahr.

Begrenzte serverseitige Logik. Cloud Functions können einige serverseitige Verarbeitung übernehmen, aber komplexe Geschäftslogik — mehrstufige Transaktionen, Datenaggregation, Hintergrundverarbeitung — erfordert entweder kreative Workarounds oder sowieso ein separates Backend.

Entscheidung: Firebase vs Traditionelles Backend

Faktor Firebase PostgreSQL + API
Zeit zum MVP Tage Wochen
Operativer Overhead Nahe null Moderat
Abfrageflexibilität Begrenzt Volles SQL
Kosten bei Skalierung Unvorhersehbar Vorhersehbar
Anbieter-Lock-in Hoch Niedrig
Offline-Unterstützung Eingebaut Muss gebaut werden
Komplexe Geschäftslogik Schwierig Natürlich
Erforderliches Team Nur Frontend Frontend + Backend

Redis: Caching, Queues und mehr

Redis ist für die meisten Anwendungen keine primäre Datenbank (obwohl Redis mit Persistenz-Modulen diese Rolle erfüllen kann). Es ist ein Hochleistungs-Datenstruktur-Speicher, der bei spezifischen Problemen glänzt.

Caching

Der häufigste Redis-Anwendungsfall. Cachen Sie teure Datenbankabfragen, API-Antworten oder berechnete Ergebnisse.

import redis
import json

r = redis.Redis(host='localhost', port=6379, db=0)

def get_user_profile(user_id: str):
    # Check cache first
    cached = r.get(f"user:{user_id}")
    if cached:
        return json.loads(cached)

    # Cache miss — query database
    profile = db.query("SELECT * FROM users WHERE id = %s", user_id)

    # Cache for 5 minutes
    r.setex(f"user:{user_id}", 300, json.dumps(profile))
    return profile

Session-Speicher

Redis' Key-Value-Modell mit TTL-Unterstützung (Time-to-Live) ist eine natürliche Wahl für Session-Daten. Es ist schneller als datenbankgestützte Sessions und einfacher als JWT-basierte Lösungen für zustandsbehaftete Anwendungen.

Rate Limiting

def is_rate_limited(user_id: str, limit: int = 100, window: int = 60) -> bool:
    key = f"rate:{user_id}"
    current = r.incr(key)
    if current == 1:
        r.expire(key, window)
    return current > limit

Job Queues

Redis Lists und Streams eignen sich hervorragend als Job Queues. Bibliotheken wie Bull (Node.js), Celery (Python) und Sidekiq (Ruby) verwenden Redis als ihren Message Broker.

Wann Redis nicht verwenden

  • Als einzige Datenbank. Redis ist standardmäßig In-Memory. Selbst mit Persistenz (RDB-Snapshots oder AOF-Logs) ist es nicht für Daten konzipiert, die Sie sich nicht leisten können zu verlieren.
  • Für komplexe Abfragen. Redis-Datenstrukturen (Strings, Lists, Sets, Sorted Sets, Hashes) sind mächtig, aber nicht wie eine Datenbank abfragbar. Sie greifen auf Daten per Schlüssel zu, nicht nach beliebigen Bedingungen.
  • Wenn Sie kein Caching-Problem haben. Redis zu einem Stack hinzuzufügen, der kein Caching braucht, fügt operative Komplexität ohne Nutzen hinzu. Eine PostgreSQL-Abfrage, die 5 ms dauert, muss nicht gecacht werden.

Mehrere Datenbanken verwenden

Die meisten Produktionsanwendungen von moderater Komplexität verwenden mehr als eine Datenbank. Der Schlüssel ist, jede für das zu nutzen, was sie am besten kann, anstatt eine Datenbank zu zwingen, alles zu handhaben.

Ein gängiges Muster für eine Webanwendung:

  • PostgreSQL für Kern-Geschäftsdaten (Benutzer, Bestellungen, Produkte).
  • Redis für Caching, Sessions und Rate Limiting.
  • S3 (oder Äquivalent) für Dateispeicher (Bilder, Dokumente, Backups).

Für eine Echtzeit-Anwendung:

  • PostgreSQL für persistente Daten und komplexe Abfragen.
  • Redis für Pub/Sub und Caching.
  • Firebase/Supabase für Echtzeit-Synchronisation zu mobilen Clients.

Das Integrationsmuster

Bei Verwendung mehrerer Datenbanken etablieren Sie klare Zuständigkeit. Jedes Datenstück hat eine autoritative Quelle, und andere Systeme sind Caches oder Ansichten dieser Daten.

PostgreSQL (source of truth)
    ├── Redis (read cache, expires after TTL)
    ├── Elasticsearch (search index, synced via change data capture)
    └── Firebase (mobile sync, updated via webhooks)

Haben Sie nie zwei Datenbanken, die sich beide als Eigentümer derselben Daten betrachten. Dieser Weg führt zu Konsistenz-Albträumen, die fast unmöglich zu debuggen sind.

Migrationsüberlegungen

Wenn Sie erkennen, dass Sie die falsche Datenbank gewählt haben, ist eine Migration möglich, aber teuer. Hier sind die praktischen Überlegungen:

MongoDB zu PostgreSQL ist die häufigste Migration, die ich gesehen habe. Der übliche Grund ist, dass die Anwendung über Dokumentabfragen hinausgewachsen ist und komplexe Joins, Transaktionen oder Aggregationen benötigte. Die Migration umfasst das Design eines relationalen Schemas, das Schreiben von Transformationsskripten und die Aktualisierung jeder Datenbankabfrage in der Anwendung. Rechnen Sie mit zwei bis vier Wochen für eine mittelkomplexe Anwendung.

PostgreSQL zu MongoDB ist seltener, kommt aber vor, wenn das Datenmodell einer Anwendung überwiegend dokumentenorientiert wird. Die Migration ist mechanisch einfacher (Tabellen in Dokumente abflachen), erfordert aber ein Umdenken bei jeder Abfrage und den Verlust von Transaktionsgarantien.

Firebase zu PostgreSQL ist die schwierigste Migration, weil es nicht nur ein Datenbankwechsel ist — es ist ein Architekturwechsel. Sie müssen eine API-Schicht bauen, Authentifizierung implementieren, Echtzeit-Listener durch WebSockets oder Polling ersetzen und Offline-Synchronisation handhaben. Das kommt einem Neuschrieb näher als einer Migration.

Die beste Migration ist die, die Sie vermeiden. Verbringen Sie einen zusätzlichen Tag mit dem Nachdenken über Ihr Datenmodell vorab. Sprechen Sie mit jemandem, der eine ähnliche Anwendung gebaut hat. Die Kosten der richtigen Datenbankwahl am Anfang sind immer geringer als die Kosten einer späteren Migration.

Kostenanalyse

Datenbankkosten bei Skalierung können überraschend sein, besonders bei Managed Services.

Service Free Tier Kleine Produktion Mittlere Produktion
Supabase (PostgreSQL) 500 MB, 2 Projekte ~25 $/Monat (8 GB, 2 Kerne) ~100 $/Monat (32 GB, 4 Kerne)
Neon (PostgreSQL) 0,5 GB Storage ~19 $/Monat ~69 $/Monat
MongoDB Atlas 512 MB geteilt ~57 $/Monat (M10 dediziert) ~200 $/Monat (M30)
Firebase Firestore 1 GB Storage, 50k Reads/Tag ~25-100 $/Monat (variiert stark) 100-1000 $/Monat (abfrageabhängig)
Redis Cloud 30 MB ~7 $/Monat (250 MB) ~60 $/Monat (1 GB)
PlanetScale (MySQL) 5 GB, 1 Mrd. Row Reads/Monat ~39 $/Monat ~99 $/Monat

Firebases Kostenunberechenbarkeit verdient Betonung. Ich habe Projekte gesehen, bei denen die Kosten monatelang unter 30 $/Monat blieben und dann nach einem Feature-Launch, der die Dokumentlese-Vorgänge erhöhte, auf 300 $ sprangen. Bei PostgreSQL oder MongoDB korrelieren die Kosten mit der Maschinengröße, was vorhersehbar ist.

Mein tatsächlicher Entscheidungsprozess

Wenn ich ein neues Projekt starte, läuft die Entscheidung normalerweise so ab:

  1. Standardmäßig PostgreSQL, es sei denn, es gibt einen spezifischen Grund dagegen.
  2. Redis hinzufügen, wenn die Anwendung Caching-Bedarf, Rate Limiting oder Job Queues hat.
  3. Firebase/Supabase erwägen, wenn die Anwendung Mobile-First mit Echtzeit-Anforderungen ist und das Team klein ist.
  4. MongoDB erwägen, wenn das Datenmodell wirklich dokumentenorientiert mit minimalen relationalen Anforderungen ist.
  5. Spezialdatenbanken hinzufügen (Elasticsearch, TimescaleDB, etc.) nur wenn ein spezifischer Workload es erfordert.

Dieses Framework hat mir über eine Reihe von Projekten gute Dienste geleistet, von Restaurant-Management-Plattformen bis zu mobilen Gesundheitsanwendungen. Die zentrale Erkenntnis ist, dass die Datenbank Infrastruktur ist — sie sollte den Anforderungen Ihrer Anwendung dienen, nicht Ihre Architektur bestimmen. Wählen Sie die langweilige Option, die funktioniert, und investieren Sie Ihre Engineering-Ressourcen in die Teile der Anwendung, die Sie differenzieren.

DU

Danil Ulmashev

Full Stack Developer

Interesse an einer Zusammenarbeit?