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 clientae publicschemi (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}_customerper 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_userper 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 DEFINERper eseguire come utente speciale con il permesso di inserire / aggiornare / cancellare sulle tabelle (nota : session_userviene utilizzato perché userecurrent_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.