Am unteren Ende läuft es im Grunde auf "Können Sie absolut sagen, dass Sie keine gemeinsamen Daten haben?" Im Gegensatz zu MySQL ist die Datenbank in PostgresQL eine absolute Grenze. Sie können nicht, SELECT zip_code FROM common.city_zip WHERE city=...
wenn Sie mit separaten Datenbanken gehen (zumindest nicht ohne dblink
).
Wenn Sie überhaupt gemeinsam genutzte Daten haben, ähnelt das "Schema" von postgresql dem, was mysql als "Datenbank" bezeichnet . Du kannst CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
. Sie würden ein Schema für jeden Client erstellen, der Benutzer des Clients würde sein Schema zuerst in seinem Suchpfad haben, und Berechtigungen würden erteilt, damit der Benutzer von Client A Zugriff auf das clienta
und die public
Schemas (und ihre Tabellen) hat.
Ihr Problem wird sein, dass am oberen Ende der Anzahl der Clients jede Tabelle als Datei gespeichert wird. Unabhängig davon, ob Sie eine Datenbank pro Client, ein Schema pro Client verwenden oder etwas Ähnliches ${client}_customer
für Ihre Tabellennamen verwenden, werden Sie dies tun Wahrscheinlich stoßen Sie bei 10.000 Clients auf Limits für Dateiskriptoren, selbst wenn Sie nur eine Tabelle pro Client hatten (plus einen Dateiskriptor pro Verbindung). Natürlich können Sie die maximale Anzahl von Dateideskriptoren des Kernels im laufenden Betrieb mit sysctl anpassen, aber das Pro-Prozess-Limit (ulimit) erfordert einen Neustart von postgresql, wenn Sie es beim ersten Mal zu niedrig einstellen.
Die Alternative besteht darin, "eine große Tabelle" mit einer Client-Spalte zu haben, die angibt, zu welchem Client diese Zeile gehört (idealerweise nach Benutzername, wenn Sie einen Benutzer pro Client haben, erleichtert dies die Dinge unter einer Menge). Indem Sie den Clients überhaupt keinen Zugriff auf diese Tabelle gewähren, können Sie clientspezifische Ansichten erstellen (oder session_user
zur Identifizierung des aktuellen Clients verwenden). Aktualisierungen können jedoch nicht direkt über eine Ansicht durchgeführt werden. Sie müssten definierte Funktionen zum Einfügen / Aktualisieren / Löschen in die Tabelle haben (ein Satz von Funktionen pro Client oder Verwendung session_user
), wobei die Funktionen verwendet werden SECURITY DEFINER
, um als spezieller Benutzer mit der Berechtigung zum Einfügen / Aktualisieren / Löschen in die Tabellen ausgeführt zu werden (Hinweis : session_user
wird verwendet, weil user
undcurrent_user
basieren auf dem aktuellen Kontext und innerhalb einer SECURITY DEFINER-Funktion ist dies immer der Benutzer, der die Funktion definiert hat.
In Bezug auf die Leistung weiß ich ehrlich gesagt nicht, was mit 10000 Datenbanken in postgresql passieren würde, im Gegensatz zu einer großen Tabelle mit Daten von 10000 Clients. Ein korrektes Indexdesign sollte verhindern, dass die große Tabelle langsam abgefragt wird.
Ich werde sagen, dass ich hier für jeden Client separate Datenbanken verwendet habe (wir fügen Server hinzu, um das System nutzbar zu halten, und verschieben Client-Datenbanken nach Bedarf auf neue Server, sodass wir niemals auf 10.000 Datenbanken auf einem Server zugreifen können). Ich musste die Daten einzelner Clients aus Backups zum Debuggen oder aufgrund von Benutzerfehlern regelmäßig wiederherstellen, was ein absoluter Albtraum für das Design "one big table" wäre. Wenn Sie beabsichtigen, die Anpassung Ihres Produkts an Ihre Kunden zu verkaufen, kann das Design "one big table" Sie möglicherweise daran hindern, das Datenmodell anzupassen.
pg_dump -n
psql -E
\dn
Ohne weitere Details zu Ihrer Anwendung ist es schwierig zu sagen, dass Sie durch diese Einrichtung zusätzliche Sicherheit erhalten. Wenn jeder Client eine Verbindung zur Web-App herstellt und sich ein freigegebener Benutzer von der Web-App zur Datenbank befindet, haben Sie Ihre Daten nicht auf eine Weise isoliert, die sich von der Verwendung einer einzelnen monolithischen Datenbank unterscheidet. Durch den Zugriff auf Ihre Daten über ordnungsgemäß parametrisierte gespeicherte Prozeduren erhalten Sie die Isolationsstufe, die Sie suchen, ohne die administrativen Probleme bei der Verwaltung von mehr als 10.000 Datenbanken auf einer beliebigen Anzahl von Servern.
Ich persönlich habe eine ähnliche Einrichtung auf einem einzelnen Datenbankserver ausgeführt, wobei nur parametrisierte gespeicherte Prozeduren verwendet wurden, die auf eine einzelne Datenbank treffen. Wenn Sie sicherstellen können, dass der einzige Zugriff auf die Datenbank über gespeicherte Prozeduren erfolgt, besteht keine Gefahr, dass sich Daten in den Ergebnissen vermischen.
Wenn Sie mit Ihrem Design fortfahren möchten, sind hier meine Hauptanliegen:
ulimit -n
Auf Ihrem Host-Betriebssystem gehen die offenen Dateideskriptoren ( ) ausquelle
SELECT * WHERE clientId = 3
ausführt, liegt ein Sicherheitsleck vor.