Alla fine, si riduce sostanzialmente a "puoi assolutamente dire che non hai dati condivisi?" A differenza di mysql, il database è un punto di riferimento assoluto in postgresql. Non puoi SELECT zip_code FROM common.city_zip WHERE city=...
se vai con database separati (almeno non senza dblink
).
Se hai dei dati condivisi, lo "schema" di postgresql è simile a quello che mysql chiama "database" . Puoi CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
. Si potrebbe creare uno schema per ogni cliente, che l'utente del cliente avrebbe il loro schema prima nel loro percorso di ricerca, e le autorizzazioni sarebbe stato concesso in modo che l'utente del client A avrebbe accesso alla clienta
e public
schemi (e le loro tabelle).
Il tuo problema sarà che nella parte alta del numero di client, ogni tabella viene archiviata come file, quindi se vai con un database per client, uno schema per client o usi qualcosa di simile ${client}_customer
per i nomi delle tue tabelle, probabilmente si imbatteranno in limiti di filedescriptor con client 10k anche se si avesse solo una tabella per client (più un filedescriptor per connessione). Naturalmente, è possibile regolare al volo il numero massimo di descrittori di file del kernel usando sysctl, ma il limite per processo (ulimit) richiederà il riavvio di postgresql se lo si imposta su un valore troppo basso la prima volta.
L'alternativa è avere "una grande tabella" con una colonna client che identifichi a quale client appartiene quella riga (idealmente, per nome utente se hai un utente per client, questo rende le cose sottostanti MOLTO più facili). Non garantendo alcun accesso a questa tabella da parte dei client, è possibile creare viste specifiche del client (o utilizzare session_user
per identificare il client corrente). Tuttavia, gli aggiornamenti non possono essere eseguiti direttamente tramite una vista. Dovresti avere funzioni definite per inserire / aggiornare / eliminare sulla tabella (un set di funzioni per client o altro usando session_user
) con le funzioni che usano SECURITY DEFINER
per eseguire come utente speciale con il permesso di inserire / aggiornare / cancellare sulle tabelle (nota : session_user
viene utilizzato perché user
ecurrent_user
si basano sul contesto corrente e all'interno di una funzione DEFINER DI SICUREZZA sarebbe sempre l'utente che ha definito la funzione).
Dal punto di vista delle prestazioni, al di là del problema fd, onestamente non so cosa succederebbe con 10000 database in postgresql, rispetto a una tabella di grandi dimensioni con 10000 client di dati al suo interno. Una corretta progettazione dell'indice dovrebbe impedire che la tabella di grandi dimensioni sia lenta da interrogare.
Dirò che sono andato con database separati per ogni client qui (aggiungiamo server per mantenere il sistema utilizzabile, spostando i database client su nuovi server secondo necessità, quindi non arriveremo mai a 10k database su un server). Ho dovuto ripristinare i dati dei singoli clienti dai backup per il debug o a causa di errori dell'utente su base regolare, qualcosa che sarebbe stato un vero incubo sul design di "una grande tabella". Inoltre, se intendi vendere la personalizzazione del tuo prodotto ai tuoi clienti, il design di "un tavolo unico" potrebbe finire per ostacolarti per quanto riguarda la possibilità di personalizzare il modello di dati.