Ich arbeite an einer zukünftigen mandantenfähigen Webanwendung, die Tausende von Benutzern unterstützen muss. Die App wird auf dem Java-basierten Play! MVC Framework mit JPA / Hibernate und PostgreSQL.
Ich habe Guy Naors Vortrag auf Schreiben von Multi-Tenant-Anwendungen in Rails , in denen er über einige Ansätze zur Mandantenfähigkeit spricht (die Datenisolierung nimmt ab, je weiter man die Liste durchläuft):
Ich habe mich auf Ansatz Nr. 2 festgelegt, wo eine Benutzer-ID irgendeiner Art aus einer Anfrage heraus analysiert wird und dann benutzt wird, um auf diesen Benutzer-Tablespace zuzugreifen. Ein Befehl postgres SET search_path TO customer_schema,public
wird angegeben, bevor eine Abfrage durchgeführt wird, um sicherzustellen, dass die Tabellen des Kunden das Ziel einer Abfrage sind. Dies ist leicht mit @Before
Controller-Annotationen in Controller-Methoden in Play! möglich (dies ist der Ansatz, den Guy in seinem Rails-Beispiel verwendete). Der Suchpfad in postgres verhält sich genau wie der $PATH
in einem Betriebssystem; fantastisch!
All dies hörte sich gut an, aber ich hatte sofort Schwierigkeiten, es auf einem JDBC / Hibernate / JPA-Stack zu implementieren, weil es scheinbar keine Möglichkeit gibt, Schemas zur Laufzeit dynamisch zu wechseln.
Es scheint, dass Datenbankverbindungen von einer Verbindungsfactory statisch konfiguriert werden (siehe: So verwalten Sie viele Schemas in einer Datenbank mithilfe des Ruhezustands ). Ich habe ähnliche Fragen mit ähnlichen Antworten auf die Verwendung mehrerer SessionFactorys pro Benutzer gefunden, aber da ich verstehe, dass SessionFactorys schwergewichtige Objekte sind, ist es unglaubwürdig, dass Sie Hunderte von Benutzern, geschweige denn Tausende von Benutzern, diese Route unterstützen können.
Ich habe mich nicht vollständig auf den zweiten Ansatz geeinigt, aber ich habe ihn auch für Ansatz Nr. 3 noch nicht ganz aufgegeben.
Sie können den Befehl
ausführen %Vor% so oft wie nötig innerhalb derselben Verbindung / Sitzung / Transaktion. Es ist nur ein anderer Befehl wie SELECT 1;
. Mehr dazu im Handbuch .
Natürlich können Sie auch search_path
pro Benutzer voreinstellen.
Wenn jeder Benutzer oder viele Benutzer ein Schema haben, das ihrem Benutzernamen entspricht, können Sie einfach mit Standardeinstellung in postgresql.conf :
%Vor% Weitere Möglichkeiten zum Festlegen des search_path
hier :
Wie geht die Auflösung des Suchpfad-Einflusskennzeichens und das "aktuelle Schema"
Ab Hibernate 4.0 wird Mandantenfähigkeit auf der Ebene des Diskriminators (customerID), des Schemas und der Datenbank nativ unterstützt. Siehe den Quellcode hier und den Unit-Test hier .
Die Schwierigkeit besteht darin, dass, während der Dateiname des Komponententests der SchemaBasedMultientrancyTest ist, die verwendete MultitenancyStrategy Datenbank ist. Ich kann keine Beispiele dafür finden, wie es basierend auf einem Schema funktioniert, aber vielleicht reicht der Komponententest aus, um weiterzumachen ...
Obwohl sharding nach Schema üblich ist, finden Sie diesen Beitrag von der Wohnung Juwel Autoren einige Nachteile abdecken.
Bei Citus shard wir über die oben genannte Option # 3, und Sie können mehr in unserem Use-Case-Anleitung in der Dokumentation.
Tags und Links java hibernate postgresql playframework jdbc