PostgreSQL: Ist es besser, mehrere Datenbanken mit jeweils einem Schema oder eine Datenbank mit mehreren Schemas zu verwenden?

147

Nach diesem Kommentar zu einer meiner Fragen überlege ich, ob es besser ist, eine Datenbank mit X-Schemata zu verwenden oder umgekehrt.

Meine Situation: Ich entwickle eine Webanwendung, bei der ich bei der Registrierung (tatsächlich) eine Datenbank erstelle (nein, es ist kein soziales Netzwerk: Jeder muss Zugriff auf seine eigenen Daten haben und darf niemals die Daten des anderen Benutzers sehen). .

So habe ich es für die vorherige Version meiner Anwendung verwendet (die immer noch unter MySQL ausgeführt wird): Über die Plesk-API mache ich für jede Registrierung Folgendes:

  1. Erstellen Sie einen Datenbankbenutzer mit eingeschränkten Berechtigungen.
  2. Erstellen Sie eine Datenbank, auf die nur der zuvor erstellte Benutzer und der Superuser zugreifen können (zur Wartung).
  3. Füllen Sie die Datenbank

Jetzt muss ich dasselbe mit PostgreSQL tun (das Projekt wird ausgereift und MySQL ... erfüllt nicht alle Anforderungen).

Ich muss alle Datenbanken / Schemasicherungen unabhängig voneinander haben: pg_dump funktioniert auf beide Arten einwandfrei und für Benutzer, die so konfiguriert werden können, dass sie nur auf ein Schema oder eine Datenbank zugreifen.

Angenommen, Sie sind erfahrenere PostgreSQL-Benutzer als ich. Was ist Ihrer Meinung nach die beste Lösung für meine Situation und warum?

Wird es Leistungsunterschiede bei der Verwendung der $ x-Datenbank anstelle von $ x-Schemas geben? Und welche Lösung ist in Zukunft besser zu warten (Zuverlässigkeit)?

Alle meine Datenbanken / Schemata haben immer die gleiche Struktur!

Für das Sicherungsproblem (mit pg_dump) ist es möglicherweise besser, eine Datenbank und viele Schemas zu verwenden und alle Schemas gleichzeitig zu sichern: Das Wiederherstellen ist ganz einfach. Laden Sie den Hauptspeicherauszug in einen Entwicklungscomputer und sichern Sie dann nur das benötigte Schema: dort ist ein zusätzlicher Schritt, aber das Dumping des gesamten Schemas scheint schneller zu sein als das Dumping nacheinander.

UPDATE 2012

Nun, die Anwendungsstruktur und das Design haben sich in den letzten zwei Jahren sehr verändert. Ich verwende immer noch den one db with many schemasAnsatz, habe aber immer noch eine Datenbank für jede Version meiner Anwendung:

Db myapp_01
    \_ my_customer_foo_schema
    \_ my_customer_bar_schema
Db myapp_02
    \_ my_customer_foo_schema
    \_ my_customer_bar_schema

Bei Sicherungen speichere ich regelmäßig jede Datenbank und verschiebe sie dann auf dem Entwicklungsserver.

Ich verwende auch das PITR / WAL-Backup, aber wie ich bereits sagte, muss ich wahrscheinlich nicht alle Datenbanken auf einmal wiederherstellen. Daher wird es wahrscheinlich in diesem Jahr verworfen (in meiner Situation ist dies nicht der beste Ansatz ).

Der One-DB-Many-Schema-Ansatz hat seitdem für mich sehr gut funktioniert, auch wenn die Anwendungsstruktur komplett geändert wurde:

Fast hätte ich vergessen: Alle meine Datenbanken / Schemata haben immer die gleiche Struktur!

... jetzt hat jedes Schema seine eigene Struktur, die sich dynamisch ändert und auf den Datenfluss des Benutzers reagiert.

Strae
quelle
"Alle meine Datenbanken / Schemata werden jemals die gleiche Struktur haben!" Meinst du, sie haben alle die gleiche Struktur? Oder nie?
Osama Al-Maadeed
Sorry, ja, sie haben alle für immer die gleiche Struktur: Wenn ich eine ändere, ändere ich sie alle;)
Strae
Wenn Sie 1000 Kunden haben, bedeutet dies, dass Sie 1000 Schema aktualisieren müssen?
Joshua Partogi
@jpartogi: Ja, aber ich muss nur die Tabellenstruktur aktualisieren, nicht die Daten.
Strae
Also, worauf hast du dich endlich eingelassen? Eine Frage, obwohl die Leistung von Abfragen usw. durch Tablespaces gesteuert werden kann, Schemata, die zu einer gleichwertigen Leistung von Multi-DB gegenüber Multi-Schema führen, Auswirkungen auf WAL-Protokolle ???
Kapil

Antworten:

113

Ein PostgreSQL- "Schema" entspricht in etwa einer MySQL- "Datenbank". Das Vorhandensein vieler Datenbanken in einer PostgreSQL-Installation kann problematisch werden. Viele Schemata funktionieren ohne Probleme. Sie möchten also definitiv mit einer Datenbank und mehreren Schemas in dieser Datenbank arbeiten.

Kquinn
quelle
33
Dies. Mit Postgres können Sie keine Datenbanken abfragen, was ziemlich ärgerlich sein kann.
Matt B
81
"Viele Datenbanken in einer PostgreSQL-Installation zu haben, kann problematisch werden" - bitte klären Sie; ist es allgemein oder in diesem speziellen Fall problematisch und warum?
Akaihola
33
"Der häufigste Anwendungsfall für die Verwendung mehrerer Schemas in einer Datenbank ist das Erstellen einer Software-as-a-Service-Anwendung, bei der jeder Kunde sein eigenes Schema hat. Obwohl diese Technik überzeugend erscheint, empfehlen wir dringend, sie abzulehnen, da sie zahlreiche Fälle verursacht hat Betriebsprobleme. Beispielsweise kann bereits eine mäßige Anzahl von Schemas (> 50) die Leistung des Datenbank-Snapshots-Tools " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan
16
@NeilMcGuigan: Interessanterweise scheint dies die gegenteilige Schlussfolgerung aus Kquinns (akzeptierter) Antwort zu sein.
Carbokation
8
Wenn Sie jedoch eine Datenbank mit vielen Schemas haben, ist es praktisch unmöglich, ein einziges Schema davon zu sichern. Ich verwende eine einzelne Postgres-Datenbank mit mehr als 3000 Schemas und pg_dump schlägt nur mit einem Speicherfehler fehl, wenn Sie versuchen, ein einzelnes Schema zu sichern. Ich frage mich, ob dies anders wäre, wenn ich stattdessen 3000 Datenbanken hätte.
Machisuji
27

Auf jeden Fall werde ich mich für den One-DB-Many-Schemas-Ansatz entscheiden. Auf diese Weise kann ich die gesamte Datenbank sichern, aber in vielerlei Hinsicht nur eine sehr einfach wiederherstellen:

  1. Speichern Sie die Datenbank (das gesamte Schema), laden Sie den Speicherauszug in eine neue Datenbank, sichern Sie nur das benötigte Schema und stellen Sie es in der Hauptdatenbank wieder her.
  2. Legen Sie das Schema einzeln einzeln ab (aber ich denke, die Maschine wird auf diese Weise mehr leiden - und ich erwarte etwa 500 Schemas!)

Ansonsten habe ich beim Googeln gesehen, dass es keine automatische Prozedur zum Duplizieren eines Schemas gibt (wobei eines als Vorlage verwendet wird), aber viele schlagen Folgendes vor:

  1. Erstellen Sie ein Vorlagenschema
  2. Wenn Sie duplizieren müssen, benennen Sie es mit einem neuen Namen um
  3. Wirf es weg
  4. Benennen Sie es zurück
  5. Stellen Sie den Speicherauszug wieder her
  6. Die Magie ist geschafft.

Ich habe dafür zwei Zeilen in Python geschrieben. Ich hoffe, sie können jemandem helfen (in 2 Sekunden geschriebener Code, verwenden Sie ihn nicht in der Produktion):

import os
import sys
import pg

# Take the new schema name from the second cmd arguments (the first is the filename)
newSchema = sys.argv[1]

# Temperary folder for the dumps
dumpFile = '/test/dumps/' + str(newSchema) + '.sql'

# Settings
db_name = 'db_name'
db_user = 'db_user'
db_pass = 'db_pass'
schema_as_template = 'schema_name'

# Connection
pgConnect = pg.connect(dbname= db_name, host='localhost', user= db_user, passwd= db_pass)

# Rename schema with the new name
pgConnect.query("ALTER SCHEMA " + schema_as_template + " RENAME TO " + str(newSchema))

# Dump it
command = 'export PGPASSWORD="' + db_pass + '" && pg_dump -U ' + db_user + ' -n ' + str(newSchema) + ' ' + db_name + ' > ' + dumpFile
os.system(command)

# Rename back with its default name
pgConnect.query("ALTER SCHEMA " + str(newSchema) + " RENAME TO " + schema_as_template)

# Restore the previous dump to create the new schema
restore = 'export PGPASSWORD="' + db_pass + '" && psql -U ' + db_user + ' -d ' + db_name + ' < ' + dumpFile
os.system(restore)

# Want to delete the dump file?
os.remove(dumpFile)

# Close connection
pgConnect.close()
Strae
quelle
14

Ich würde sagen, gehen Sie mit mehreren Datenbanken und mehreren Schemata :)

Schemata in PostgreSQL ähneln Paketen in Oracle, falls Sie mit diesen vertraut sind. Datenbanken sollen zwischen ganzen Datensätzen unterscheiden, während Schemata eher Datenentitäten ähneln.

Beispielsweise könnten Sie eine Datenbank für eine gesamte Anwendung mit den Schemas "UserManagement", "LongTermStorage" usw. haben. "UserManagement" würde dann die Tabelle "User" sowie alle gespeicherten Prozeduren, Trigger, Sequenzen usw. enthalten, die für die Benutzerverwaltung benötigt werden.

Datenbanken sind ganze Programme, Schemata sind Komponenten.

Peter Mortensen
quelle
4
... und so habe ich 1 Datenbank mit innerhalb der Schemas: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Mh ... scheint kein verlässlicher Weg zu sein ... und was ist mit der Leistung? Und was ist mit dem Code meiner Anwendung (wird PHP und Python sein)? so viele Schemata ..
Strae
7
@Strae: Ich lese dies als: Jeder Kunde hat seine Datenbank customer1_database, customer2_database und in diesen Datenbanken haben Sie user_schema, documents_schema.
Frankhommers
6

In einem PostgreSQL-Kontext empfehle ich, eine Datenbank mit mehreren Schemas zu verwenden, da Sie (z. B.) UNION ALL über Schemas hinweg, jedoch nicht über Datenbanken hinweg können. Aus diesem Grund ist eine Datenbank wirklich vollständig von einer anderen Datenbank isoliert, während Schemas nicht von anderen Schemas innerhalb derselben Datenbank isoliert sind.

Wenn Sie aus irgendeinem Grund in Zukunft Daten über Schemas hinweg konsolidieren müssen, ist dies problemlos über mehrere Schemas hinweg möglich. Bei mehreren Datenbanken würden Sie mehrere Datenbankverbindungen benötigen und die Daten aus jeder Datenbank "manuell" nach Anwendungslogik sammeln und zusammenführen.

Letztere haben in einigen Fällen Vorteile, aber zum größten Teil halte ich den Ansatz mit einer Datenbank und mehreren Schemata für nützlicher.

emax
quelle
4

Eine Reihe von Schemata sollte leichter sein als eine Reihe von Datenbanken, obwohl ich keine Referenz finden kann, die dies bestätigt.

Wenn Sie die Dinge jedoch wirklich sehr getrennt halten möchten (anstatt die Webanwendung so umzugestalten, dass eine "Kunden" -Spalte zu Ihren Tabellen hinzugefügt wird), möchten Sie möglicherweise dennoch separate Datenbanken verwenden: Ich behaupte, dass Sie die Wiederherstellung einfacher durchführen können auf diese Weise die Datenbank eines bestimmten Kunden - ohne die anderen Kunden zu stören.

Troels Arvin
quelle