PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

no postgresql, as partições ou vários bancos de dados são mais eficientes?


Eu recomendaria procurar informações nas listas de discussão do PostgreSQL sobre design multilocatário. Tem havido muita discussão lá, e a resposta se resume a "depende". Existem compensações em todos os sentidos entre isolamento, desempenho e manutenibilidade garantidos.

Uma abordagem comum é usar um único banco de dados, mas um esquema (namespace) por cliente com a mesma estrutura de tabela em cada esquema, além de um esquema compartilhado ou comum para dados iguais em todos eles. Um esquema PostgreSQL é como um "banco de dados" MySQL em que você pode consultar em diferentes esquemas, mas eles são isolados por padrão. Com os dados do cliente em esquema separado, você pode usar o search_path configuração, geralmente via ALTER USER customername SET search_path = 'customerschema, sharedschema' para garantir que cada cliente veja seus dados e apenas seus dados.

Para proteção adicional, você deve REVOKE ALL FROM SCHEMA customerschema FROM public então GRANT ALL ON SCHEMA customerschema TO thecustomer então eles são os únicos com algum acesso a ele, fazendo o mesmo com cada uma de suas mesas. Seu pool de conexões pode fazer login com uma conta de usuário fixa que não GRANT acesso ed a qualquer esquema de cliente, mas tem o direito de SET ROLE para se tornar qualquer cliente. (Faça isso dando a eles a associação de cada função de cliente com o conjunto NOINHERIT para que os direitos tenham que ser explicitamente reivindicados por meio de SET ROLE ). A conexão deve imediatamente SET ROLE para o cliente em que está operando atualmente. Isso permitirá que você evite a sobrecarga de fazer novas conexões para cada cliente, mantendo uma forte proteção contra erros do programador que levam ao acesso aos dados do cliente errado. Desde que o pool faça um DISCARD ALL e/ou um RESET ROLE antes de entregar conexões para o próximo cliente, isso lhe dará um isolamento muito forte sem a frustração de conexões individuais por usuário.

Se o seu ambiente de aplicativo da Web não tiver um pool de conexões decente integrado (digamos, você está usando PHP com conexões persistentes), você realmente precisa colocar um bom pool de conexões no lugar entre o Pg e o servidor web de qualquer maneira, porque muitas conexões com o backend prejudicarão seu desempenho. PgBouncer e PgPool-II são as melhores opções, e podem cuidar de fazer o DISCARD ALL e RESET ROLE para você durante a transferência da conexão.

A principal desvantagem dessa abordagem é a sobrecarga com a manutenção de tantas tabelas, pois seu conjunto básico de tabelas não compartilhadas é clonado para cada cliente. Isso aumentará à medida que o número de clientes aumentar, até o ponto em que o grande número de tabelas a serem examinadas durante as execuções de autovacuum começa a ficar caro e em que qualquer operação dimensionada com base no número total de tabelas no banco de dados fica mais lenta. Isso é mais um problema se você estiver pensando em ter muitos milhares ou dezenas de milhares de clientes no mesmo banco de dados, mas eu fortemente recomendamos que você faça alguns testes de dimensionamento com esse design usando dados fictícios antes de se comprometer com ele.

A abordagem ideal provavelmente serão tabelas únicas com segurança automática em nível de linha controlando a visibilidade da tupla, mas infelizmente isso é algo que o PostgreSQL ainda não tem. Parece que está a caminho graças ao trabalho do SEPostgreSQL adicionando infraestrutura e APIs adequadas, mas não está no 9.1.