Multi-Tenant-Datenbankarchitektur ist ein Entwurf, der viele Kunden in einer Datenschicht speichert – isoliert per Zeile, Schema oder eigener Datenbank. Diese drei Isolationsstufen sind der gesamte Entscheidungsraum – alles andere in diesem Thema sind Folgen: wie Migrationen laufen, was eine Wiederherstellung kostet, wo der Noisy Neighbor wohnt und wie weit jedes Muster skaliert.
Das Wichtigste in Kürze
| Frage | Antwort |
|---|---|
| Die drei Muster | Shared Schema (Tenant-ID pro Zeile) · Schema pro Tenant · Datenbank pro Tenant |
| Das Cloud-Vokabular | Dieselben drei: pool · bridge · silo |
| Die Standardwahl | Shared Schema, sofern nicht Compliance oder Skalierung Isolation erzwingen |
| Praktische Obergrenzen | Silo: einige Hundert Tenants · Bridge: ~1.000 · Pool: Millionen (mit Sharding: unbegrenzt) |
| Die eiserne Regel | Isolation in der Datenbank durchsetzen, nicht in jeder Abfrage |
Die drei Muster, in SQL
-- Muster 1 · Shared Schema ("pool"): ein Satz Tabellen, Tenant auf jeder Zeile
CREATE TABLE invoices (
tenant_id uuid NOT NULL,
id bigint GENERATED ALWAYS AS IDENTITY,
total numeric(10,2),
PRIMARY KEY (tenant_id, id) -- Tenant führt: bereit für Index und Sharding
);
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_rows ON invoices
USING (tenant_id = current_setting('app.tenant')::uuid);
-- Muster 2 · Schema pro Tenant ("bridge"): eine Datenbank, je ein Namensraum
CREATE SCHEMA tenant_acme; -- dieselben Tabellen, pro Tenant wiederholt
-- Muster 3 · Datenbank pro Tenant ("silo"): vollständige physische Trennung
CREATE DATABASE tenant_acme; -- stärkste Isolation; von allem N Stück
Auf einem verwalteten Backend wird dieselbe Garantie ohne SQL ausgedrückt: Die Zugriffskontrolle sitzt auf den Daten selbst, also hält die Isolation auf jedem Pfad – API, Dashboard oder SDK:
// JavaScript / Node.js — Back4app JS SDK
// The same query for every tenant — ACLs scope results server-side
const query = new Parse.Query('Invoice');
const invoices = await query.find({ sessionToken: user.getSessionToken() });
// Only rows this tenant's role can read come back. No WHERE clause to forget. // Flutter / Dart — Back4app Flutter SDK
// The same query for every tenant — ACLs scope results server-side
final query = QueryBuilder<ParseObject>(ParseObject('Invoice'));
final response = await query.query();
// The session's role decides which rows exist, before results leave the server
if (response.success) {
print('${response.results?.length} invoices visible to this tenant');
} // iOS / Swift — Back4app Swift SDK
// The same query for every tenant — ACLs scope results server-side
let query = Invoice.query()
query.find { result in
if case .success(let invoices) = result {
print("\(invoices.count) invoices visible to this tenant")
}
} // Android / Kotlin — Back4app Android SDK
// The same query for every tenant — ACLs scope results server-side
val query = ParseQuery.getQuery<ParseObject>("Invoice")
query.findInBackground { invoices, e ->
if (e == null) {
Log.d("Billing", "${invoices.size} invoices visible to this tenant")
}
} Shared Schema vs. Schema pro Tenant vs. Datenbank pro Tenant
| Dimension | Shared Schema | Schema pro Tenant | Datenbank pro Tenant |
|---|---|---|---|
| Isolation | Logisch, pro Zeile | Namensraum | Physisch |
| Obergrenze an Tenants | Millionen | ~Hunderte–1.000 | Dutzende–wenige Hundert |
| Kosten pro Tenant | Am niedrigsten | Mittel | Am höchsten |
| Migrationen | Einmal ausführen, trifft alle | × N ausführen, orchestriert | × N ausführen, orchestriert |
| Wiederherstellung pro Tenant | Schwer (selektives Kopieren) | Mittel | Trivial (eine DB zurückspielen) |
| Noisy Neighbor | Am stärksten ausgesetzt | Teilweise eingedämmt | Ausgeschlossen |
| Anpassung pro Tenant | Am schwersten | Pro Schema möglich | Am einfachsten |
| Einen Tenant anlegen | Eine Zeile einfügen | Ein Schema anlegen | Eine Datenbank bereitstellen |
Die Details, die wehtun
- Indizierung beginnt beim Tenant.
tenant_idgehört in jede Tabelle – auch dort, wo Joins sie redundant aussehen lassen – und eröffnet jeden zusammengesetzten Index:(tenant_id, created_at), nicht umgekehrt. Jede echte Abfrage ist auf einen Tenant eingegrenzt; die Indizes sollten es auch sein. - Migrationen vervielfachen sich mit der Isolation. Die Flexibilität des Silo kostet eine Orchestrierungsschicht: Versionsverfolgung pro Tenant, Logik für Wiederholungsversuche, Drift-Erkennung. Teams unterschätzen diese Zeile stärker als jede andere in der Tabelle.
- Zeilenbasierte Sicherheit hat ihr operatives Kleingedrucktes. Policies stützen sich auf Einstellungen pro Verbindung, die mit den Modi des Connection Pooling zusammenwirken – setzen Sie den Tenant pro Transaktion und testen Sie den Pooler. Auditieren Sie außerdem, welche Rollen RLS umgehen; Superuser-Pfade sind das klassische Loch.
- Die Arithmetik der Verbindungen. Ein Pool je Tenant-Datenbank erschöpft die Verbindungen schnell; Entwürfe mit Shared Schema teilen sich einen Pool – ein weiterer stiller Vorteil des Pool-Musters, der erst im großen Maßstab sichtbar wird.
- Die Asymmetrie der Wiederherstellung treibt die Stufen. “Können Sie nur uns auf gestern zurücksetzen?” ist eine Vertragsfrage von Großkunden; muss die Antwort Ja lauten, gehört dieser Tenant in ein Silo – was direkt zum Hybrid führt.
Skalierung und der hybride Endzustand
Der Wachstumspfad des Pool-Musters ist Sharding nach Tenant: mehrere Datenbanken mit Shared Schema, jede mit einem Ausschnitt der Tenants, dazu ein Katalog, der Tenant → Shard abbildet (das Open-Source-Projekt Citus hat das in PostgreSQL eingebaut, samt dem Verschieben eines stark belasteten Tenants auf einen eigenen Knoten). Zusammen mit gestuften Tarifen ergibt das die Architektur, zu der die meisten reifen SaaS-Produkte konvergieren: der kostenlose Tarif im Pool, mittelgroße Tenants über mehrere Shards gepoolt und die wenigen regulierten oder riesigen Tenants im Silo – mit tenant_id in jedem Schema, überall, damit jeder Tenant ohne Umbau zwischen den Stufen wechseln kann. Die Beweglichkeit der Tenants ist die Eigenschaft, für die man vom ersten Tag an entwirft; nachrüsten lässt sie sich kaum.
Typische Anwendungsfälle
- B2B-SaaS. Der prägende Fall: Jeder Workspace, jede Organisation, jedes Team in Ihrem Produkt ist ein Tenant in einem dieser Muster.
- Freemium-Produkte im großen Maßstab. Tausende kleiner kostenloser Tenants im Pool, zu Grenzkosten nahe null – die Ökonomie, die kostenlose Tarife möglich macht.
- Regulierte Branchen. Kunden aus Gesundheitswesen, Finanzwesen und Rechtsberatung, die vertraglich Silos verlangen – aus derselben Codebasis bedient, über den Hybrid.
- Agenturen und Plattformen. Eine Anwendung bedient viele Kundenorganisationen, jede mit ihrer eigenen Grenze.
- Interne Plattformen für mehrere Teams. Abteilungen als Tenants auf geteilten Werkzeugen – dieselben Muster, freundlicheres Bedrohungsmodell.
Welches Muster sollten Sie wählen? Entscheidungsmatrix
| Shared Schema, wenn … | Schema pro Tenant, wenn … | Datenbank pro Tenant, wenn … |
|---|---|---|
| Die Tenants zahlreich und klein sind | Die Tenants im dreistelligen Bereich liegen | Die Tenants wenige und groß sind |
| Die Kosten pro Tenant gegen null gehen müssen | Mäßige Isolation etwas Betriebsaufwand wert ist | Compliance physische Trennung verlangt |
| Eine Migration alle aktualisieren soll | Anpassungen am Schema pro Tenant nötig sind | Wiederherstellung pro Tenant vertraglich zugesagt ist |
| Self-Service-Anmeldung sofort greifen soll | Tenants im menschlichen Tempo hinzukommen | Jeder Tenant eine Bereitstellung rechtfertigt |
| Sie beim Wachsen sharden werden | Sie die Zahl der Tenants deckeln werden | Sie Migrationen × N automatisieren werden |
Und die Meta-Antwort: Wählen Sie pro Stufe, nicht pro Unternehmen – hybride Entwürfe stecken jeden Tenant in das billigste Muster, das seine Anforderungen erfüllt, und verschieben ihn, wenn sich diese Anforderungen ändern.
Grenzen und Trade-offs
- Shared Schema: der stärkste Bedarf an Isolation, die die Datenbank durchsetzt – ein fehlender Filter ist ein Datenleck, weshalb RLS oder ACLs in der Datenschicht nicht verhandelbar sind und keine optionale Härtung.
- Schema pro Tenant: die unbequeme Mitte – Migrationsorchestrierung wie im Silo, schwächere Isolation als im Silo, und Metadaten-Grenzen der Datenbank, die überraschend früh erreicht werden.
- Datenbank pro Tenant: alles × N – Migrationen, Backups, Monitoring, Verbindungen, Kosten – und Analytik über Tenants hinweg wird zum Data-Engineering-Projekt.
- Alle drei: Der Tenant-Kontext durchdringt alles (Abfragen, Caches, Jobs, Logs), und ein Wechsel zwischen den Mustern ist teuer ohne Disziplin bei den Kennungen vom ersten Tag an: global eindeutige Bezeichner und
tenant_id-Spalten überall, auch in Silos.
Multi-Tenant-Daten mit Back4app
Back4app ist eine Open-Source-Plattform für Backend as a Service (BaaS), die eine verwaltete Datenbank, automatisch generierte REST- und GraphQL-APIs, Authentifizierung, Dateispeicher und Serverless-Funktionen mit Cloud Code kombiniert. Die Antwort der Plattform auf die eiserne Regel dieses Artikels – Isolation in der Datenbank durchsetzen – lautet: ACLs pro Objekt, Rollen pro Tenant und Klassenberechtigungen, von der Plattform bei jeder Anfrage von jeder Oberfläche geprüft, wie die Code-Tabs oben zeigen. Das ist das Muster Shared Schema, befreit vom Risiko der WHERE-Klausel; die technische Vertiefung zur zeilenbasierten Sicherheit führt das vollständige Muster auf einer Dokumentdatenbank vor, und die Sicht auf der Hosting-Ebene desselben Themas deckt die Infrastrukturschicht darüber ab.
Häufige Fragen
Welche drei Muster für Multi-Tenant-Datenbanken gibt es?
Shared Schema – ein Satz Tabellen, jede Zeile trägt eine Tenant-Kennung; Schema pro Tenant – eine Datenbank, je Kunde ein eigener Namensraum von Tabellen; und Datenbank pro Tenant – vollständige physische Trennung. Leitfäden zur Cloud-Architektur nennen dieselben drei pool, bridge und silo. Reale Systeme mischen sie zunehmend und verteilen Tenants nach Größe und Compliance-Anforderungen auf die Muster.
Geteilte Datenbank oder Datenbank pro Tenant – was sollte ich wählen?
Der Standard, über den Einigkeit herrscht, ist Shared Schema, sofern nichts Isolation erzwingt: regulatorische Auflagen, vertragliche Datentrennung, umfangreiche Anpassungen pro Tenant oder einzelne Tenants, die groß genug für eigene Ressourcen sind. Shared Schema maximiert die Dichte und minimiert den Betrieb; Datenbanken pro Tenant maximieren die Isolation und vervielfachen alles andere – Migrationen, Backups, Verbindungen, Kosten.
Wie viele Tenants verkraftet jedes Muster?
Die praktischen Obergrenzen aus dem Produktivbetrieb: Datenbank pro Tenant läuft bequem bis zu einigen Dutzend oder niedrigen dreistelligen Tenant-Zahlen, bevor der Betrieb überhandnimmt; Schema pro Tenant erreicht einige Hundert bis etwa tausend, bevor Metadaten und die Orchestrierung von Migrationen ächzen; Shared Schema skaliert auf Tausende bis Millionen Tenants, und Sharding des Shared Schema nach Tenant dehnt das praktisch grenzenlos aus.
Wie verhindert man, dass ein Tenant die Daten eines anderen sieht?
Mit mehrschichtiger Verteidigung, niemals mit einer WHERE-Klausel allein. Die Eingrenzung auf den Tenant in der Anwendung (Middleware oder Filter im ORM) ist die erste Schicht; von der Datenbank durchgesetzte zeilenbasierte Sicherheit ist die zweite – Policies, die jede Abfrage nach dem aktuellen Tenant filtern, ganz gleich was die Anwendung vergessen hat. In Entwürfen mit Shared Schema ist ein einziger fehlender Filter ein Datenabfluss zwischen Tenants; deshalb sollte die Datenbank selbst die Grenze durchsetzen.
Wie funktionieren Schema-Migrationen in den verschiedenen Mustern?
Im Shared Schema aktualisiert eine Migration alle Tenants auf einmal – einfach, mit einem entsprechenden Schadensradius. Bei Schema oder Datenbank pro Tenant muss dieselbe Migration einmal pro Tenant laufen: Hunderte Ausführungen, die Orchestrierung, Versionsverfolgung und Drift-Erkennung brauchen, denn ein fehlgeschlagener Lauf lässt einen Tenant auf einem älteren Schema zurück. Das Migrationswerkzeug ist die versteckte Steuer der Isolation.
Lassen sich die Daten eines einzelnen Tenants wiederherstellen?
Bei Datenbank pro Tenant trivial – stellen Sie diese Datenbank auf einen beliebigen Zeitpunkt wieder her, ohne jemanden sonst zu berühren. Im Shared Schema ist es wirklich schwierig: Das Backup enthält alle, Sie stellen also auf einer Nebeninstanz wieder her und kopieren die Zeilen des Tenants gezielt zurück. Die Wiederherstellung pro Tenant ist eines der stärksten praktischen Argumente, mit denen Großkunden Isolationsstufen fordern.
Wie indiziert man eine Multi-Tenant-Datenbank mit Shared Schema?
Nehmen Sie die Tenant-Kennung in jede Tabelle auf – auch dort, wo sie redundant wirkt – und stellen Sie sie an den Anfang Ihrer zusammengesetzten Indizes, damit jedes Abfragemuster den Tenant zuerst nutzt. Die Tenant-Spalte zum führenden Teil des Primärschlüssels zu machen bereitet die Daten zugleich auf späteres Sharding nach Tenant vor – den üblichen Wachstumspfad.
Was ist Sharding nach Tenant?
Einen Entwurf mit Shared Schema auf mehrere Datenbanken aufteilen, wobei alle Zeilen eines Tenants auf genau einem Shard liegen und ein Katalog Tenants auf Shards abbildet. Das erhält die Dichte des Shared Schema und deckelt zugleich die Größe jeder einzelnen Datenbank; außerdem lassen sich stark belastete Tenants auf ruhigere Shards verschieben. Der Preis sind der Katalog, das Werkzeug zum Rebalancing und der Verlust trivialer Abfragen über Tenants hinweg.