Freigeben über


Modellieren von Mehrmandanten-SaaS-Apps in Azure Cosmos DB for PostgreSQL

GILT FÜR: Azure Cosmos DB for PostgreSQL (unterstützt von der Citus-Datenbankerweiterung auf PostgreSQL)

Mandanten-ID als Shardschlüssel

Die Mandanten-ID ist die Spalte am Stamm des Workloads oder am oberen Rand der Hierarchie in Ihrem Datenmodell. Beispielsweise wäre es in diesem SaaS-E-Commerce-Schema die Store-ID:

Diagramm: Tabellen, in denen die Spalte „store_id“ hervorgehoben ist

Dieses Datenmodell wäre typisch für ein Unternehmen wie Shopify. Es hostet Websites für mehrere Onlinestores, in denen jeder Store mit seinen eigenen Daten interagiert.

  • Dieses Datenmodell verfügt über eine Reihe von Tabellen: Stores, Produkte, Bestellungen, Linienelemente und Länder/Regionen.
  • Die Tabelle "Stores" befindet sich oben in der Hierarchie. Produkte, Bestellungen und Linienelemente sind allen Stores zugeordnet, also niedriger in der Hierarchie.
  • Die Tabelle mit Ländern/Regionen ist nicht mit einzelnen Geschäften verbunden, es gehört zu den Stores.

In diesem Beispiel ist store_id, der sich am oberen Rand der Hierarchie befindet, der Bezeichner für Mandanten. Es ist der richtige Shardschlüssel. Die Auswahl von store_id als Shardschlüssel ermöglicht das Sammeln von Daten über alle Tabellen für einen einzelnen Store auf einem einzelnen Worker.

Die Kolocierung von Tabellen durch den Store bietet Vorteile:

  • Bietet SQL Abdeckung wie Fremdschlüssel, JOINs. Transaktionen für einen einzelnen Mandanten werden auf einem einzelnen Workerknoten lokalisiert, auf dem jeder Mandant vorhanden ist.
  • Erreicht eine einzelstellige Millisekundenleistung. Abfragen für einen einzelnen Mandanten werden an einen einzelnen Knoten weitergeleitet, anstatt parallelisiert zu werden, wodurch Netzwerkhops optimiert und die Berechnung/Arbeitsspeicher weiterhin skaliert wird.
  • Es skaliert. Da die Anzahl der Mandanten wächst, können Sie Knoten hinzufügen und die Mandanten auf neue Knoten neu ausbalancieren oder sogar große Mandanten auf ihre eigenen Knoten isolieren. Mit der Mandantenisolation können Sie dedizierte Ressourcen bereitstellen.

Diagramm: Tabellen, die an den selben Knoten angeordnet sind

Optimales Datenmodell für Multimandanten-Apps

In diesem Beispiel sollten wir die storespezifischen Tabellen nach Speicher-ID verteilen und countries zu einer Referenztabelle machen.

Diagramm: Tabellen, in denen die Spalte „store_id“ überall hervorgehoben ist

Beachten Sie, dass mandantenspezifische Tabellen über die Mandanten-ID verfügen und verteilt werden. In unserem Beispiel werden Stores, Produkte und line_items verteilt. Die restlichen Tabellen sind Referenztabellen. In unserem Beispiel ist die Tabelle mit Ländern/Regionen eine Referenztabelle.

-- Distribute large tables by the tenant ID

SELECT create_distributed_table('stores', 'store_id');
SELECT create_distributed_table('products', 'store_id', colocate_with => 'stores');
-- etc for the rest of the tenant tables...

-- Then, make "countries" a reference table, with a synchronized copy of the
-- table maintained on every worker node

SELECT create_reference_table('countries');

Große Tabellen sollten alle über die Mandanten-ID verfügen.

  • Wenn Sie eine vorhandene Mehrmandanten-App zu Azure Cosmos DB for PostgreSQL migrieren, müssen Sie möglicherweise ein wenig denormalisieren und die Spalte mit der Mandanten-ID in großen Tabellen hinzufügen, wenn sie fehlt, und dann die fehlenden Werte der Spalte auffüllen.
  • Stellen Sie für neue Apps in Azure Cosmos DB for PostgreSQL sicher, dass die Mandanten-ID in allen mandantenspezifischen Tabellen vorhanden ist.

Stellen Sie sicher, dass die Mandanten-ID auf primärer, eindeutiger und Fremdschlüsseleinschränkungen für verteilte Tabellen in Form eines zusammengesetzten Schlüssels enthalten ist. Wenn beispielsweise eine Tabelle über einen Primärschlüssel von id verfügt, machen Sie ihn zum zusammengesetzten Schlüssel (tenant_id,id). Es müssen keine Schlüssel für Referenztabellen geändert werden.

Abfrageüberlegungen für die beste Leistung

Verteilte Abfragen, die nach der Mandanten-ID gefiltert werden, werden in Multimandanten-Apps am effizientesten ausgeführt. Stellen Sie sicher, dass Ihre Abfragen immer auf einen einzelnen Mandanten angewendet werden.

SELECT *
  FROM orders
 WHERE order_id = 123
   AND store_id = 42;  -- ← tenant ID filter

Es ist notwendig, den Mandanten-ID-Filter hinzuzufügen, auch wenn die ursprünglichen Filterbedingungen eindeutig die gewünschten Zeilen identifizieren. Der Mandanten-ID-Filter ist zwar scheinbar redundant, teilt Azure Cosmos DB for PostgreSQL aber mit, wie die Abfrage an einen einzelnen Workerknoten weitergeleitet wird.

Wenn Sie zwei verteilte Tabellen verknüpfen, stellen Sie sicher, dass beide Tabellen auf einen einzelnen Mandanten angewendet werden. Die Bereichsdefinition kann durchgeführt werden, indem sichergestellt wird, dass die Verknüpfungsbedingungen die Mandanten-ID enthalten.

SELECT sum(l.quantity)
  FROM line_items l
 INNER JOIN products p
    ON l.product_id = p.product_id
   AND l.store_id = p.store_id   -- ← tenant ID in join
 WHERE p.name='Awesome Wool Pants'
   AND l.store_id='8c69aa0d-3f13-4440-86ca-443566c1fc75';
       -- ↑ tenant ID filter

Es gibt Hilfsprogrammbibliotheken für mehrere beliebte Anwendungsframeworks, die es einfach machen, eine Mandanten-ID in Abfragen einzuschließen. Hier sind Anweisungen:

Nächste Schritte

Jetzt haben Sie die Datenmodellierung für skalierbare Apps abgeschlossen. Der nächste Schritt besteht darin, die Datenbank mithilfe der Programmiersprache Ihrer Wahl zu verbinden und abzufragen.