PostgreSQL: è meglio usare più database con uno schema ciascuno o un database con più schemi?


147

Dopo questo commento a una delle mie domande, sto pensando se è meglio usare un database con schemi X o viceversa.

La mia situazione: sto sviluppando un'applicazione web in cui, quando le persone si registrano, creo (in realtà) un database (no, non è un social network: tutti devono avere accesso ai propri dati e non vedere mai i dati dell'altro utente) .

È così che ho usato per la versione precedente della mia applicazione (che è ancora in esecuzione su MySQL): attraverso l'API di Plesk, per ogni registrazione, faccio:

  1. Creare un utente del database con privilegi limitati;
  2. Creare un database a cui è possibile accedere solo dall'utente creato in precedenza e dal superutente (per manutenzione)
  3. Popolare il database

Ora, dovrò fare lo stesso con PostgreSQL (il progetto sta diventando maturo e MySQL ... non soddisfa tutte le esigenze).

Devo avere tutti i backup di database / schemi indipendenti: pg_dump funziona perfettamente in entrambi i modi e lo stesso per gli utenti che possono essere configurati per accedere a un solo schema o un database.

Quindi, supponendo che tu sia un utente PostgreSQL più esperto di me, quale pensi sia la migliore soluzione per la mia situazione e perché?

Ci saranno differenze di prestazioni usando il database $ x anziché gli schemi $ x? E quale soluzione sarà meglio mantenere in futuro (affidabilità)?

Tutti i miei database / schemi avranno sempre la stessa struttura!

Per il problema dei backup (usando pg_dump), forse è meglio usare un database e molti schemi, scaricando tutti gli schemi in una volta: il ripristino sarà abbastanza semplice caricare il dump principale in una macchina di sviluppo e quindi scaricare e ripristinare solo lo schema necessario: lì è un ulteriore passaggio, ma il dumping di tutti gli schemi sembra più rapido rispetto al dumping uno per uno.

AGGIORNAMENTO 2012

Bene, la struttura e il design dell'applicazione sono cambiati molto negli ultimi due anni. Sto ancora usando l' one db with many schemasapproccio, ma ho ancora un database per ogni versione della mia applicazione:

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

Per i backup, eseguo il dump periodico di ciascun database e quindi lo spostamento dei backup sul server di sviluppo.

Sto anche usando il backup PITR / WAL ma, come ho detto prima, non è probabile che dovrò ripristinare tutto il database in una volta ... quindi probabilmente verrà chiuso quest'anno (nella mia situazione non è l'approccio migliore ).

L'approccio one-db-many-schema ha funzionato molto bene per me da ora, anche se la struttura dell'applicazione è totalmente cambiata:

Ho quasi dimenticato: tutti i miei database / schemi avranno sempre la stessa struttura!

... ora, ogni schema ha una propria struttura che cambia in modo dinamico reagendo al flusso di dati degli utenti.


"tutti i miei database / schemi avranno mai la stessa struttura!" vuoi dire che hanno tutti la stessa struttura? O mai più?
Osama Al-Maadeed,

Scusate, sì, hanno tutti la stessa struttura per sempre: se ne cambio una, cambierò tutte;)
Strae

Se hai 1000 clienti, significa che devi aggiornare lo schema 1000?
Joshua Partogi,

@jpartogi: sì, ma devo aggiornare solo la struttura delle tabelle, non i dati.
Strae,

Quindi, per cosa sei andato finalmente? Una domanda, sebbene, sebbene le prestazioni delle query, ecc. Possano essere controllate da tablespace, gli schemi risultino in prestazioni equivalenti di multi-db vs multi-schema, qualsiasi impatto sui log WAL ???
Kapil,

Risposte:


113

Uno "schema" PostgreSQL è all'incirca lo stesso di un "database" MySQL. Avere molti database su un'installazione PostgreSQL può diventare problematico; avere molti schemi funzionerà senza problemi. Quindi sicuramente vuoi andare con un database e più schemi all'interno di quel database.


33
Questo. Postgres non ti consente di eseguire query tra i database, il che può essere piuttosto fastidioso.
matt b

81
"Avere molti database su un'installazione PostgreSQL può diventare problematico" - chiarire; è problematico in generale o in questo caso specifico, e perché?
Akaihola,

33
"Il caso d'uso più comune per l'utilizzo di più schemi in un database è la creazione di un'applicazione software-as-a-service in cui ogni cliente ha il proprio schema. Sebbene questa tecnica sembri avvincente, raccomandiamo fortemente di non farlo poiché ha causato numerosi casi di problemi operativi. Ad esempio, anche un numero moderato di schemi (> 50) può influire gravemente sulle prestazioni dello strumento di snapshot del database Heroku " devcenter.heroku.com/articles/heroku-postgresql
Neil McGuigan,

16
@NeilMcGuigan: È interessante notare che sembra essere la conclusione opposta dalla risposta (accettata) di kquinn.
carbocation

8
Avere un database con molti schemi renderà praticamente impossibile scaricare un singolo schema di quelli, però. Sto eseguendo un singolo database Postgres con oltre 3000 schemi e pg_dump non riesce con un errore di memoria insufficiente se si tenta di scaricare un singolo schema. Mi chiedo se questo sarebbe diverso se avessi invece 3000 database.
Machisuji,

27

Sicuramente, sceglierò l'approccio one-db-many-schemas. Questo mi permette di scaricare tutto il database, ma ripristinarne uno molto facilmente, in molti modi:

  1. Scaricare il db (tutto lo schema), caricare il dump in un nuovo db, scaricare solo lo schema di cui ho bisogno e ripristinare nel db principale.
  2. Scarica lo schema separatamente, uno per uno (ma penso che la macchina soffrirà di più in questo modo - e mi aspetto come 500 schemi!)

Altrimenti, cercando su google ho visto che non esiste una procedura automatica per duplicare uno schema (usando uno come modello), ma molti suggeriscono in questo modo:

  1. Crea uno schema modello
  2. Quando è necessario duplicare, rinominarlo con un nuovo nome
  3. Gettalo via
  4. Rinominalo di nuovo
  5. Ripristina il dump
  6. La magia è fatta.

Ho scritto due righe in Python per farlo; Spero che possano aiutare qualcuno (in-2-secondi-codice-scritto, non usarlo in produzione):

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()

14

Direi, vai con più database E schemi multipli :)

Gli schemi in PostgreSQL sono molto simili ai pacchetti in Oracle, nel caso tu ne abbia familiarità. I database hanno lo scopo di differenziare intere serie di dati, mentre gli schemi sono più simili a entità di dati.

Ad esempio, potresti avere un database per un'intera applicazione con gli schemi "UserManagement", "LongTermStorage" e così via. "UserManagement" conterrà quindi la tabella "User", nonché tutte le procedure memorizzate, i trigger, le sequenze, ecc. Necessarie per la gestione dell'utente.

I database sono interi programmi, gli schemi sono componenti.


4
... e quindi avrò 1 database, con dentro gli schemi: $ customer1_user_schema, $ customer2_user_schema, $ customer3_user_schema, $ customer1_documents_schema, $ customer2_documents_schema, $ customer3_documents_schema? Mh ... non sembra un modo affidabile ... e le prestazioni? E il codice della mia applicazione (sarà php e python)? così tanti schemi ..
Strae,

7
@Strae: sto leggendo questo come: ogni cliente ha il suo database customer1_database, customer2_database e all'interno di quei database hai user_schema, documents_schema.
Frankhommers,

6

In un contesto PostgreSQL, raccomando di usare un db con più schemi, in quanto è possibile (ad es.) UNION ALL tra gli schemi, ma non tra i database. Per tale motivo, un database è davvero completamente isolato da un altro database mentre gli schemi non sono isolati da altri schemi all'interno dello stesso database.

Se in futuro dovessi consolidare i dati tra gli schemi, sarà facile farlo su più schemi. Con più database è necessario disporre di più connessioni db e raccogliere e unire i dati da ciascun database "manualmente" in base alla logica dell'applicazione.

Questi ultimi presentano dei vantaggi in alcuni casi, ma per la maggior parte ritengo che l'approccio a un database con schemi multipli sia più utile.


4

Un certo numero di schemi dovrebbe essere più leggero di un numero di database, anche se non riesco a trovare un riferimento che lo confermi.

Ma se vuoi davvero mantenere le cose molto separate (invece di refactoring dell'applicazione web in modo che una colonna "cliente" venga aggiunta alle tue tabelle), potresti comunque voler usare database separati: asserisco che puoi ripristinare più facilmente i ripristini di il database di un determinato cliente in questo modo - senza disturbare gli altri clienti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.