PostgreSQL: Est-il préférable d'utiliser plusieurs bases de données avec un schéma chacune, ou une base de données avec plusieurs schémas?

147

Après ce commentaire à l'une de mes questions, je me demande s'il vaut mieux utiliser une base de données avec des schémas X ou vice versa.

Ma situation: je développe une application web où, lorsque les gens s'inscrivent, je crée (en fait) une base de données (non, ce n'est pas un réseau social: chacun doit avoir accès à ses propres données et ne jamais voir les données de l'autre utilisateur) .

C'est comme ça que j'ai utilisé pour la version précédente de mon application (qui est toujours en cours d'exécution sur MySQL): via l'API Plesk, pour chaque inscription, je fais:

  1. Créer un utilisateur de base de données avec des privilèges limités;
  2. Créer une base de données accessible uniquement par l'utilisateur créé précédemment et le superutilisateur (pour la maintenance)
  3. Remplir la base de données

Maintenant, je vais devoir faire de même avec PostgreSQL (le projet est en train de mûrir et MySQL ... ne répond pas à tous les besoins).

J'ai besoin d'avoir toutes les sauvegardes de bases de données / schémas indépendantes: pg_dump fonctionne parfaitement dans les deux sens, et de même pour les utilisateurs qui peuvent être configurés pour accéder à un seul schéma ou à une base de données.

Donc, en supposant que vous soyez des utilisateurs PostgreSQL plus expérimentés que moi, quelle est selon vous la meilleure solution pour ma situation, et pourquoi?

Y aura-t-il des différences de performances en utilisant la base de données $ x au lieu des schémas $ x? Et quelle solution sera la meilleure à maintenir à l'avenir (fiabilité)?

Toutes mes bases de données / schémas auront toujours la même structure!

Pour le problème des sauvegardes (en utilisant pg_dump), il est peut-être préférable d'utiliser une base de données et de nombreux schémas, vider tous les schémas à la fois: la récupération sera assez simple en chargeant le vidage principal dans une machine de développement, puis en vidant et en restaurant juste le schéma nécessaire: là est une étape supplémentaire, mais vider tous les schémas semble plus rapide que de les vider un par un.

MISE À JOUR 2012

Eh bien, la structure et la conception de l'application ont tellement changé au cours de ces deux dernières années. J'utilise toujours l' one db with many schemasapproche, mais j'ai quand même une base de données pour chaque version de mon application:

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

Pour les sauvegardes, je vide régulièrement chaque base de données, puis je déplace les sauvegardes sur le serveur de développement.

J'utilise également la sauvegarde PITR / WAL mais, comme je l'ai déjà dit, il est peu probable que je doive restaurer toutes les bases de données en même temps ... donc elle sera probablement rejetée cette année (dans ma situation, ce n'est pas la meilleure approche ).

L'approche one-db-many-schema a très bien fonctionné pour moi depuis maintenant, même si la structure de l'application est totalement modifiée:

J'ai presque oublié: toutes mes bases de données / schémas auront toujours la même structure!

... maintenant, chaque schéma a sa propre structure qui change de manière dynamique en fonction du flux de données des utilisateurs.

Strae
la source
"toutes mes bases de données / schémas auront toujours la même structure!" voulez-vous dire qu'ils ont tous la même structure? Ou jamais?
Osama Al-Maadeed
Désolé, oui, ils ont tous la même structure pour toujours: si j'en change un, je les changerai tous;)
Strae
Si vous avez 1000 clients, cela signifie que vous devez mettre à jour 1000 schémas?
Joshua Partogi
@jpartogi: oui, mais je dois mettre à jour uniquement la structure des tables, pas les données.
Strae
Alors, pour quoi êtes-vous finalement allé? Une question, cependant, bien que les performances des requêtes, etc. puissent être contrôlées par des tablespaces, des schémas aboutissant à des performances équivalentes de multi-db vs multi-schema, tout impact sur les journaux WAL ???
Kapil

Réponses:

113

Un "schéma" PostgreSQL est à peu près le même qu'une "base de données" MySQL. Avoir de nombreuses bases de données sur une installation PostgreSQL peut devenir problématique; avoir de nombreux schémas fonctionnera sans problème. Vous voulez donc absolument utiliser une base de données et plusieurs schémas dans cette base de données.

kquinn
la source
33
Ce. Postgres ne vous permet pas d'interroger les bases de données, ce qui peut être assez ennuyeux.
matt b le
81
"Avoir de nombreuses bases de données sur une installation PostgreSQL peut devenir problématique" - veuillez clarifier; est-ce problématique en général ou dans ce cas précis, et pourquoi?
akaihola
33
"Le cas d'utilisation le plus courant de l'utilisation de plusieurs schémas dans une base de données est la création d'une application logicielle en tant que service dans laquelle chaque client a son propre schéma. Bien que cette technique semble convaincante, nous la déconseillons vivement car elle a causé de nombreux cas de problèmes opérationnels. Par exemple, même un nombre modéré de schémas (> 50) peut gravement affecter les performances de l'outil d'instantanés de base de données de Heroku " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan
16
@NeilMcGuigan: Fait intéressant, cela semble être la conclusion opposée à la réponse (acceptée) de kquinn.
carbocation
8
Cependant, avoir une base de données avec de nombreux schémas rendra pratiquement impossible de vider un seul schéma de ceux-ci. J'exécute une seule base de données postgres avec plus de 3000 schémas et pg_dump échoue simplement avec une erreur de mémoire insuffisante si vous essayez de vider un seul schéma. Je me demande si ce serait différent si j'avais 3000 bases de données à la place.
Machisuji
27

Certainement, je vais opter pour l'approche one-db-many-schemas. Cela me permet de vider toute la base de données, mais d'en restaurer une seule très facilement, de plusieurs manières:

  1. Videz la base de données (tout le schéma), chargez la sauvegarde dans une nouvelle base de données, videz uniquement le schéma dont j'ai besoin et restaurez-la dans la base de données principale.
  2. Videz le schéma séparément, un par un (mais je pense que la machine souffrira davantage de cette façon - et je m'attends à 500 schémas!)

Sinon, en cherchant sur Google, j'ai vu qu'il n'y a pas de procédure automatique pour dupliquer un schéma (en utilisant un comme modèle), mais beaucoup suggèrent de cette façon:

  1. Créer un modèle-schéma
  2. Lorsque vous avez besoin de dupliquer, renommez-le avec un nouveau nom
  3. Jette le
  4. Renommez-le
  5. Restaurer la décharge
  6. La magie est faite.

J'ai écrit deux lignes en Python pour ce faire; J'espère qu'ils pourront aider quelqu'un (code écrit en 2 secondes, ne l'utilisez pas en production):

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
la source
14

Je dirais, allez avec plusieurs bases de données ET plusieurs schémas :)

Les schémas dans PostgreSQL ressemblent beaucoup à des packages dans Oracle, au cas où vous en seriez familier. Les bases de données sont destinées à différencier des ensembles entiers de données, tandis que les schémas ressemblent davantage à des entités de données.

Par exemple, vous pourriez avoir une base de données pour une application entière avec les schémas "UserManagement", "LongTermStorage" et ainsi de suite. "UserManagement" contiendrait alors la table "User", ainsi que toutes les procédures stockées, déclencheurs, séquences, etc. nécessaires à la gestion des utilisateurs.

Les bases de données sont des programmes entiers, les schémas sont des composants.

Peter Mortensen
la source
4
... et donc j'aurai 1 base de données, avec à l'intérieur des schémas: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Mh ... ne semble pas un moyen fiable ... et qu'en est-il des performances? Et qu'en est-il du code de mon application (sera php et python)? tellement de schémas ..
Strae
7
@Strae: Je lis ceci comme suit: chaque client a sa base de données customer1_database, customer2_database et dans ces bases de données, vous avez user_schema, documents_schema.
frankhommers
6

Dans un contexte PostgreSQL, je recommande d'utiliser une base de données avec plusieurs schémas, comme vous pouvez (par exemple) UNION ALL entre les schémas, mais pas entre les bases de données. Pour cette raison, une base de données est vraiment complètement isolée d'une autre base de données tandis que les schémas ne sont pas isolés des autres schémas de la même base de données.

Si, pour une raison quelconque, vous devez consolider des données entre les schémas à l'avenir, il sera facile de le faire sur plusieurs schémas. Avec plusieurs bases de données, vous auriez besoin de plusieurs connexions db et collecter et fusionner les données de chaque base de données «manuellement» par la logique d'application.

Ces derniers présentent des avantages dans certains cas, mais pour l'essentiel, je pense que l'approche à une base de données et à plusieurs schémas est plus utile.

emax
la source
4

Un certain nombre de schémas devraient être plus légers qu'un certain nombre de bases de données, même si je ne trouve pas de référence qui le confirme.

Mais si vous voulez vraiment garder les choses très séparées (au lieu de refactoriser l'application web pour qu'une colonne "client" soit ajoutée à vos tables), vous pouvez toujours vouloir utiliser des bases de données séparées: j'affirme que vous pouvez plus facilement faire des restaurations de base de données d'un client particulier de cette façon - sans déranger les autres clients.

Troels Arvin
la source