Hibernate und Multi-Tenant-Datenbank mit Schemas in PostgreSQL

8

Hintergrund

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):

  1. Jeder Kunde hat eine separate Datenbank
  2. Eine Datenbank mit separaten Schemas und Tabellen (Tabellennamespaces) für jeden Kunden.
  3. Eine Datenbank mit einem Satz von Tabellen mit Kunden-ID-Spalten.

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.

Das Problem

Wie bekomme ich entweder JDBC oder Hibernate, um das dynamische Wechseln von Postgres-Schemas zur Laufzeit zu unterstützen?

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.

    
Jesse 01.12.2011, 22:33
quelle

3 Antworten

5

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.

%Vor%

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"

    
Erwin Brandstetter 02.12.2011, 01:01
quelle
1

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 ...

    
therealmitchconnors 18.01.2012 19:48
quelle
1

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.

    
Sumedh 01.08.2017 22:12
quelle