PostgreSQL如何处理大量的数据库?

我们有一个Web应用程序,其架构要求任何注册用户(一个公司,实际上)都应该与另一个隔离开来,也就是说,我将使用相同的数据模型运行相同的Web应用程序,但是为每个客户提供不同的数据集。

所以,我们确实考虑在每个客户的Postgres中创build一个不同的数据库。 这个解决scheme可以扩展到10-20K数据库吗? 多好?

有没有人有更好的解决scheme呢?

提前致谢。

在低端,基本归结为“你能说绝对没有共享数据吗?” 与mysql不同,数据库是postgresql中的绝对边界。 你不能SELECT zip_code FROM common.city_zip WHERE city=...如果你去与单独的数据库(至less不是没有dblink )。

如果你有任何共享的数据, postgresql的“模式”与mysql调用“数据库”类似 。 你可以CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...); CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...); 。 您将为每个客户端创build一个模式,该客户端的用户将首先在其searchpath中使用他们的模式,并授予权限,以便客户端A的用户可以访问客户端和public模式(及其表)。

你的问题是在#个客户端的高端,每个表都存储为一个文件,所以无论你是每个客户端一个数据库,每个客户端一个模式,还是使用类似${client}_customer表名,即使你每个客户端只有一个表(每个连接一个文件描述符),你也可能遇到 10k客户端的filedescriptor限制 。 当然,你可以使用sysctl来dynamic调整内核的最大文件描述符数量,但是如果你第一次设置得太低的话,per-process limit(ulimit)将需要重新启动postgresql。

另一种方法是用一个客户端列来标识哪个客户端属于哪个客户端(理想情况下,如果每个客户端有一个用户,则使用用户名,这使得LOT更容易)。 通过不授予客户端对该表的任何访问权限,您可以创build特定于客户端的视图(或使用session_user来标识当前客户端)。 尽pipe如此,更新不能直接通过视图完成。 您需要定义函数来在表上插入/更新/删除(每个客户端的一个函数集,或者使用session_user ),使用SECURITY DEFINER的函数作为特殊用户执行,并且具有插入/更新/删除表(注意:使用session_user是因为usercurrent_user是基于当前上下文的,而在SECURITY DEFINER函数中,这将始终是定义该函数的用户)。

在性能方面,除了fd问题之外,我真的不知道postgresql中的10000个数据库会发生什么情况,而有一个10000个客户端数据的大型表。 正确的索引devise应该防止大表查询速度慢。

我会说,我在这里为每个客户端使用不同的数据库(我们添加服务器以保持系统可用,根据需要将客户端数据库转移到新服务器,所以我们将永远不会在一台服务器上获得10k数据库)。 我不得不从备份中恢复个人客户的数据以进行debugging或者定期出现用户错误,这对于“一张大桌子”devise来说是绝对的噩梦。 另外,如果您打算向您的客户销售您的产品的定制,那么“一张大桌子”的devise可能最终会让您自定义数据模型的能力。

没有关于你的应用程序的更多细节,很难说你会从这个设置中获得额外的安全性。 如果每个客户端都连接到Web应用程序,并且有从Web应用程序到数据库的共享用户,那么您没有以与使用单个单一数据库不同的方式隔离数据。 通过正确参数化的存储过程访问数据将为您提供所需的隔离级别,而不会在pipe理任何数量的服务器上pipe理超过10,000个数据库的pipe理问题。

我亲自在单个数据库服务器上运行类似的设置,仅仅使用参数化的存储过程触发单个数据库。 如果可以保证只有通过存储过程才能访问数据库,那么结果中就不存在混合数据的危险。

如果你想要继续你的devise,这里是我的主要担忧:

  1. 用完主机操作系统上的打开的文件描述符( ulimit -n
  2. 为不同的查询模式调整10,000多个数据库
  3. pipe理10,000多个具有不同安全性问题的数据库(备份和潜在恢复,如果服务器出现故障,是否真的想要恢复10,000多个数据库?)
  4. 推出超过10,000个数据库的变化