PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Sind in Postgresql Partitionen oder mehrere Datenbanken effizienter?

Ich würde empfehlen, in den PostgreSQL-Mailinglisten nach Informationen über mandantenfähiges Design zu suchen. Es gab dort viele Diskussionen, und die Antwort läuft darauf hinaus, dass es darauf ankommt. Es gibt Kompromisse zwischen garantierter Isolierung, Leistung und Wartbarkeit.

Ein gängiger Ansatz ist die Verwendung einer einzigen Datenbank, aber eines Schemas (Namespace) pro Kunde mit der gleichen Tabellenstruktur in jedem Schema plus ein gemeinsames oder gemeinsames Schema für Daten, das für alle gleich ist. Ein PostgreSQL-Schema ist wie eine MySQL-„Datenbank“, da Sie Abfragen über verschiedene Schemas hinweg durchführen können, diese jedoch standardmäßig isoliert sind. Bei Kundendaten in einem separaten Schema können Sie den Suchpfad Einstellung, normalerweise über ALTER USER customername SET search_path ='customerschema, sharedschema' um sicherzustellen, dass jeder Kunde seine Daten und nur seine Daten sieht.

Für zusätzlichen Schutz sollten Sie REVOKE ALL FROM SCHEMA Kundenschema FROM public dann GRANT ALL ON SCHEMA Kundenschema ZUM Kunden Sie sind also die Einzigen, die Zugriff darauf haben, und machen dasselbe mit jedem ihrer Tische. Ihr Verbindungspool kann sich dann mit einem festen Benutzerkonto anmelden, das kein hat GEWÄHREN hat Zugriff auf jedes Kundenschema, hat aber das Recht auf ROLLE EINSTELLEN irgendein Kunde zu werden. (Tun Sie dies, indem Sie ihnen die Mitgliedschaft jeder Kundenrolle mit NOINHERIT-Satz gewähren, sodass Rechte explizit über SET ROLE beansprucht werden müssen ). Die Verbindung sollte sofort SET ROLE für den Kunden, als der es derzeit tätig ist. Auf diese Weise können Sie den Aufwand vermeiden, für jeden Kunden neue Verbindungen herzustellen, und gleichzeitig einen starken Schutz vor Programmierfehlern aufrechterhalten, die zum Zugriff auf die Daten des falschen Kunden führen. Solange der Pool einen DISCARD ALL und/oder ein ROLLE ZURÜCKSETZEN Bevor Sie Verbindungen an den nächsten Client weitergeben, erhalten Sie eine sehr starke Isolation ohne die Frustration einzelner Verbindungen pro Benutzer.

Wenn Ihre Webanwendungsumgebung keinen anständigen integrierten Verbindungspool hat (sagen wir, Sie verwenden PHP mit dauerhaften Verbindungen), dann wirklich müssen einen Pool für gute Verbindungen erstellen zwischen Pg und dem Webserver ohnehin vorhanden sein, da zu viele Verbindungen zum Backend Ihrer Leistung schaden. PgBouncer und PgPool-II sind die besten Optionen und können sich praktisch um DISCARD ALL kümmern und ROLLE ZURÜCKSETZEN für Sie während der Verbindungsübergabe.

Der Hauptnachteil dieses Ansatzes ist der Overhead bei der Verwaltung so vieler Tabellen, da Ihr Basissatz nicht gemeinsam genutzter Tabellen für jeden Kunden geklont wird. Mit zunehmender Kundenzahl summiert sich dies bis zu dem Punkt, an dem die schiere Anzahl der Tabellen, die während der Autovacuum-Läufe untersucht werden müssen, teuer wird und an dem jeder Vorgang, der auf der Grundlage der Gesamtzahl der Tabellen in der Datenbank skaliert wird, langsamer wird. Dies ist eher ein Problem, wenn Sie daran denken, viele Tausend oder Zehntausende von Kunden in derselben Datenbank zu haben, aber ich stark Wir empfehlen Ihnen, einige Skalierungstests mit diesem Design mit Dummy-Daten durchzuführen, bevor Sie sich darauf festlegen.

Der ideale Ansatz sind wahrscheinlich einzelne Tabellen mit automatischer Sicherheit auf Zeilenebene, die die Tupelsichtbarkeit steuern, aber leider hat PostgreSQL das noch nicht. Es sieht so aus, als wäre es dank der SEPostgreSQL-Arbeit, die geeignete Infrastruktur und APIs hinzufügt, auf dem Weg, aber es ist nicht in 9.1 enthalten.