No final, basicamente se resume a "você pode dizer com absoluta certeza que não tem dados compartilhados?" Ao contrário do mysql, o banco de dados é um limite absoluto no postgresql. Você não pode SELECT zip_code FROM common.city_zip WHERE city=...
se você for com bancos de dados separados (pelo menos não sem dblink
) .
Se você tiver algum dado compartilhado, o "esquema" do postgresql é semelhante ao que o mysql chama um "banco de dados" . Você pode CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
. Você criaria um esquema para cada cliente, o usuário desse cliente teria seu esquema primeiro em seu caminho de pesquisa e as permissões seriam concedidas para que o usuário do Cliente A tivesse acesso aos clienta
e public
schemas (e suas tabelas ).
Seu problema será que, na extremidade alta de # de clientes, cada tabela é armazenada como um arquivo, portanto, se você usa um banco de dados por cliente, um esquema por cliente ou usa algo como ${client}_customer
para seus nomes de tabelas, você provavelmente encontrará os limites do filedescriptor com clientes 10k, mesmo que você só tinha uma tabela por cliente (mais um filodescriptor por conexão). É claro, você pode ajustar o número máximo de descritores de arquivos do kernel durante a execução usando sysctl, mas o limite por processo (ulimit) exigirá a reinicialização do postgresql se você defini-lo como muito baixo na primeira vez.
A alternativa é ter "uma tabela grande" com uma coluna de cliente que identifica a qual cliente essa linha pertence (idealmente, pelo nome de usuário se você tiver um usuário por cliente, isso torna as coisas abaixo de um LOTE mais fácil). Ao não conceder nenhum acesso a essa tabela pelos clientes, você pode criar exibições específicas do cliente (ou usar session_user
para identificar o cliente atual). Atualizações não podem ser feitas diretamente através de uma visão, no entanto. Você precisaria ter funções definidas para inserir / atualizar / excluir na tabela (um conjunto de funções por cliente ou usando session_user
) com as funções usando SECURITY DEFINER
para executar como um usuário especial com permissão para inserir / atualizar / delete nas tabelas (nota: session_user
é usado porque user
e current_user
são baseados no contexto atual, e dentro de uma função SECURITY DEFINER, este sempre seria o usuário que definiu a função).
Em termos de desempenho, além da questão fd, eu sinceramente não sei o que aconteceria com 10000 bancos de dados no postgresql, em vez de ter uma tabela grande com 10000 clientes de dados. O design adequado do índice deve impedir que a tabela grande seja lenta para consultar.
Eu vou dizer que eu usei bancos de dados separados para cada cliente aqui (nós adicionamos servidores para manter o sistema utilizável, mudando bancos de dados clientes para novos servidores conforme necessário, então nunca chegaremos a 10k bancos de dados em um servidor). Eu tive que restaurar dados de clientes individuais de backups para depuração ou devido a erro do usuário em uma base regular, algo que seria um pesadelo absoluto no design de "uma grande mesa". Além disso, se você pretende vender a personalização de seu produto para seus clientes, o design de "uma grande tabela" pode acabar atrapalhando você quanto à capacidade de personalizar o modelo de dados.