在postgresql中,分区或多个数据库更高效吗?

前端之家收集整理的这篇文章主要介绍了在postgresql中,分区或多个数据库更高效吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
有一个应用程序,许多公司发布信息.每个公司的数据都是自包含的 – 没有数据重叠.

性能方面,它更好:

>在每个表的每一行上保留公司ID并让每个索引使用它?
>根据公司ID对每个表进行分区
>分区并创建用户访问每个公司以确保安全性
>创建多个数据库,每个公司一个

具有持久连接的基于Web的应用程序.

我的想法:

>新的pg连接很昂贵,因此单个数据库创建的连接较少
>只有一个字典副本似乎比200左右更有效
>多个数据库肯定比程序员错误更安全
>如果应用程序规范应该更改,以便公司共享多个数据
基地难以实施

我建议在Postgresql邮件列表中搜索有关多租户设计的信息.那里有很多讨论,答案归结为“它取决于”.在保证隔离,性能和可维护性之间存在各方面的权衡.

一种常见的方法是使用单个数据库,但每个客户一个schema(命名空间),每个模式中具有相同的表结构,以及所有数据中相同的数据的共享或公共模式. Postgresql模式就像一个MysqL数据库”,您可以跨不同的模式进行查询,但默认情况下它们是隔离的.通过单独模式中的客户数据,您可以使用search_path设置,通常通过ALTER USER customername SET search_path =’customerschema,sharedschema’来确保每个客户都能看到他们的数据,只看到他们的数据.

为了获得额外的保护,您应该REVOKE ALL FROM SCHEMA customerschema FROM public然后GRANTALL ON SCHEMA customerschema to the customer,这样他们就是唯一一个可以访问它的人,对每个表做同样的事情.然后,您的连接池可以使用固定用户帐户登录,该帐户对任何客户架构都没有GRANTed访问权限,但有权成为任何客户的SET ROLE. (通过为NOINHERIT设置每个客户角色的成员资格来实现这一点,因此必须通过SET ROLE明确声明权利).连接应立即设置为当前正在运行的客户.这样可以避免为每个客户建立新连接的开销,同时保持对程序员错误的强大保护,从而导致访问错误的客户数据.只要池在将连接交给下一个客户端之前执行DISCARD ALL和/或RESET ROLE,这将为您提供非常强大的隔离,而不会让每个用户的个别连接受挫.

如果您的Web应用程序环境内置了一个不错的连接池(例如,您使用的是持久连接的PHP),那么您确实需要在Pg和Web服务器之间放置一个good connection pool,因为连接太多了到后端会伤害你的表现. PgBouncerPgPool-II是最好的选择,在连接切换期间,您可以轻松地为您完成DISCARD ALL和RESET ROLE.

这种方法的主要缺点是维护许多表的开销,因为为每个客户克隆了基本的非共享表集.随着客户数量的增长,它会加起来,在autovacuum运行期间要检查的表的数量开始变得昂贵,并且根据数据库中的表总数进行扩展的任何操作都会减慢.如果您考虑在同一个数据库中拥有数千或数万个客户,这就更成问题了,但我强烈建议您在提交之前使用虚拟数据对此设计进行一些扩展测试.

理想的方法可能是具有自动行级安全性控制元组可见性的单表,但不幸的是Postgresql还没有.由于SEPostgresql工作添加了合适的基础设施和API,它看起来还在路上,但它不在9.1中.

猜你在找的Postgre SQL相关文章