No extremo inferior, basicamente se resume a "você pode dizer absolutamente que não possui dados compartilhados?" Diferente 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 for com bancos de dados separados (pelo menos não sem dblink
).
Se você possui algum dado compartilhado, o "esquema" do postgresql é semelhante ao que o mysql chama de "banco de dados" . Você pode CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);
. Você poderia criar um esquema para cada cliente, o usuário do cliente teria seu esquema pela primeira vez em seu caminho de pesquisa, e seria concedido permissões para que o usuário do Cliente Um teriam acesso ao clienta
e os public
esquemas (e suas tabelas).
Seu problema será que, no final de # de clientes, cada tabela é armazenada como um arquivo. Portanto, se você usar um banco de dados por cliente, um esquema por cliente ou usar algo parecido ${client}_customer
com os nomes de suas tabelas, poderá é provável que atinja os limites do filedescriptor com 10 mil clientes, mesmo que você tenha apenas uma tabela por cliente (mais um filedescriptor por conexão). Obviamente, você pode ajustar o número máximo de descritores de arquivos do kernel em tempo real usando sysctl, mas o limite por processo (ulimit) exigirá a reinicialização do postgresql se você o definir muito baixo na primeira vez.
A alternativa é ter "uma grande tabela" com uma coluna de cliente que identifique a qual cliente essa linha pertence (idealmente, por nome de usuário, se você tiver um usuário por cliente, isso facilita muito as coisas abaixo). Ao não conceder nenhum acesso a essa tabela pelos clientes, você pode criar visualizações específicas do cliente (ou usar session_user
para identificar o cliente atual). As atualizações não podem ser feitas diretamente através de uma exibição. Você precisaria ter funções definidas para inserir / atualizar / excluir na tabela (um conjunto de funções por cliente ou usar session_user
) com as funções usadas SECURITY DEFINER
para executar como um usuário especial com permissão para inserir / atualizar / excluir nas tabelas (observação : session_user
é usado porque user
ecurrent_user
são baseados no contexto atual e, dentro de uma função DEFINER DE SEGURANÇA, esse sempre seria o usuário que definiu a função).
Em termos de desempenho, além da questão fd, sinceramente não sei o que aconteceria com 10000 bancos de dados no postgresql, em vez de ter uma tabela grande com 10000 dados de clientes. O design adequado do índice deve impedir que a tabela grande seja lenta para consulta.
Eu direi que optei por bancos de dados separados para cada cliente aqui (adicionamos servidores para manter o sistema utilizável, transferindo bancos de dados de clientes para novos servidores conforme necessário, para que nunca cheguemos a 10 mil bancos de dados em um servidor). Eu tive que restaurar os dados de clientes individuais de backups para depuração ou devido a erros do usuário regularmente, algo que seria um pesadelo absoluto no design de "uma grande mesa". Além disso, se você pretende vender a personalização do seu produto para seus clientes, o design de "uma grande mesa" pode acabar atrapalhando você na capacidade de personalizar o modelo de dados.