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 dans laquelle, lorsque des personnes s'inscrivent, je crée (en fait) une base de données (non, ce n'est pas un réseau social: tout le monde doit avoir accès à ses propres données et ne jamais voir celles de l'autre utilisateur) .
C'est la façon dont j'ai utilisé la version précédente de mon application (qui tourne toujours sur MySQL): via l'API de Plesk, pour chaque enregistrement, je fais:
Maintenant, je vais devoir faire la même chose avec PostgreSQL (le projet mûrit et MySQL ... ne répond pas à tous les besoins).
J'ai besoin de toutes les sauvegardes de bases de données/schémas indépendantes: pg_dump fonctionne parfaitement dans les deux sens, et il en va de même pour les utilisateurs pouvant être configurés pour accéder à un seul schéma ou à une seule 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 préférable de maintenir à l'avenir (fiabilité)?
Toutes mes bases de données/schémas auront toujours la même structure!
Pour le problème des sauvegardes (avec pg_dump), il vaut peut-être mieux utiliser une base de données et plusieurs schémas, vider tous les schémas à la fois: la récupération sera assez simple: charger le dump principal dans une machine de développement, puis dump et restaurer uniquement le schéma nécessaire: est une étape supplémentaire, mais le dumping de tout le schéma semble plus rapide que de les jeter un à un.
Eh bien, la structure et la conception de l'application ont tellement changé au cours des deux dernières années. J'utilise toujours le one db with many schemas
approche, mais toujours, j'ai 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 à la fois ... il sera probablement rejeté cette année. (dans ma situation 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 dynamiquement en réagissant au flux de données des utilisateurs.
Un "schéma" PostgreSQL est à peu près identique à une "base de données" MySQL. Avoir plusieurs bases de données sur une installation PostgreSQL peut être problématique; avoir beaucoup de schémas fonctionnera sans problème. Donc, vous voulez vraiment aller avec une base de données et plusieurs schémas dans cette base de données.
En définitive, je vais opter pour l'approche à une base de plusieurs schémas. Cela me permet de vider toute la base de données, mais de n'en restaurer qu'une très facilement, de plusieurs manières:
Autrement, j'ai recherché sur Google qu'il n'y a pas de procédure automatique pour dupliquer un schéma (en en utilisant un comme modèle), mais beaucoup suggèrent ceci:
J'ai écrit deux lignes dans Python pour le 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()
Je dirais, allez avec plusieurs bases de données ET plusieurs schémas :)
Les schémas dans PostgreSQL ressemblent beaucoup aux packages dans Oracle, si vous les connaissez bien. Les bases de données sont conçues pour différencier des ensembles de données entiers, 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", etc. "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.
Un certain nombre de schémas devrait être plus léger qu'un certain nombre de bases de données, bien que 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 afin qu'une colonne "client" soit ajoutée à vos tables), vous pouvez toujours utiliser des bases de données séparées: J'affirme que vous pouvez plus facilement restaurer des restaurations. la base de données d'un client particulier de cette manière - sans déranger les autres clients.
Dans un contexte PostgreSQL, je recommande d'utiliser une base de données avec plusieurs schémas, comme vous pouvez (par exemple) UNION ALL sur tous 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 alors que les schémas ne sont pas isolés d'autres schémas de la même base de données.
Si, pour une raison quelconque, vous devez à l'avenir consolider les données sur plusieurs schémas, vous pourrez le faire facilement sur plusieurs schémas. Avec plusieurs bases de données, vous aurez besoin de plusieurs connexions à la base de données, ainsi que de collecter et fusionner les données de chaque base de données "manuellement" par la logique d'application.
Ces derniers ont des avantages dans certains cas, mais pour l’essentiel, j’estime que l’approche à une base de données multiple-schémas est plus utile.