当前位置: 首页 > 知识库问答 >
问题:

PostgreSQL的多租户应用程序模式

农鸿德
2023-03-14

我正在学习多租户应用程序,以及如何使用PostgreSQL的模式来实现这一点。

在研究这个主题时,我发现了一篇文章,作者描述了在多租户应用程序中使用PostgreSQL模式时的糟糕体验。主要问题是迁移性能差和数据库资源使用率高。

似乎只有一个模式(在租户之间共享表)会比每个租户有一个单独的模式带来更好的性能。但我觉得很奇怪。我的想法正好相反,因为较小表上的索引往往比较大表上的索引轻。

为什么在许多小表(在多个模式中)中分离数据时,性能会比在几个大表(在单个模式中)中分离数据时差?

共有1个答案

姜博
2023-03-14

性能并不一定更差。正如本文所解释的,根据应用程序设计和工作负载的不同,有一些特定的条件使模式方法更好或更差。让我解释一下“租户模式”与“共享表”方法的权衡:

租户模式在租户数量相对较少且相当大的情况下是最好的。这方面的一个例子是只有付费订阅用户的会计应用程序。使其成为更好的选择的因素包括:

  • 少数租户每人都有大量数据

使其成为表现不佳的选择的因素包括:

  • 很多租户,每个都只有很少的数据
  • 连接的无状态方法,其中每个请求可以是任何租户
  • 为所有表缓存元数据的客户端库或orm(如ActiveBook)
  • 对高效、高性能连池和/或缓存的需求
  • VACUUM和其他PostgreSQL管理操作的问题,这些操作在1000个表中扩展不良。

租户模式是否不利于迁移/模式更改实际上取决于您的操作方式。这不利于快速推出通用模式更改,但有利于在租户中逐步部署模式更改。

共享表更适用于租户很多,而且租户的数据非常少的情况。这方面的一个例子是一个社交媒体移动应用程序,它允许免费账户,因此有数千个被放弃的账户。使共享表模型受益的其他因素包括:

  • 对于连接池更好,因为所有连接都可以使用相同的池

共享表的主要缺点是需要在应用层的每个查询中附加租户筛选条件。这也有问题,因为:

  • 连接多个表的查询可能会执行得很差,因为租户过滤器会中断查询规划
  • 表的行数增加到1亿行可能会导致特定的性能和维护问题
  • 无法进行租户特定的应用程序更改或架构升级
  • 在服务器之间迁移租户的成本更高

因此,哪种模式“表现更好”实际上取决于哪种权衡对你的伤害最大。

还有一个混合模型“租户视图”,实际数据存储在共享表中,但每个应用程序连接都使用安全屏障视图来查看数据。这是每个模型的一些折衷。首先,它具有租户模式模型的安全优势,但也存在两种模型的一些性能缺陷。

 类似资料:
  • 我必须在j2ee中开发一个多租户SaaS应用程序,从Iaas和PaaS开始实现三种云模型,我选择了openstack和openshift origin。SaaS应用程序的第一个标准是多租户,我知道有三种方法来实现它——单独的数据库——共享数据库,单独的模式——共享数据库,共享模式。我在这里迷失了方向,因为许多框架,比如ATHENA,ORM,比如hibernate,还有TOPLINK。我需要帮助了解

  • 我已经安装了keycloak-angular包,我使用它的方式如下:https://www.npmjs.com/package/keycloak-angular 问题是,在我的应用程序中,我希望有多租户。这意味着在应用程序加载期间不知道领域名。 在说明中,它说“KeycloakService应该在应用程序加载期间使用APP_INITIALIZER标记初始化”,问题是该领域是由用户给定的,在应用程序

  • 我正在开发一个多租户反应式应用程序,使用带有r2dbc驱动程序的Spring-Webflow Spring-data-r2dbc连接到Postgresql数据库。多租户部分是基于模式的:每个租户一个模式。因此,根据上下文(例如登录的用户),请求将访问数据库的特定模式。 我正在努力研究如何在r2dbc中实现这一点。理想情况下,这将是Hibernate处理MultiTenantConnectionPr

  • 我正在使用Java、Spring、Struts2和Hibernate设计一个多租户SaaS Web应用程序。经过一些研究,我选择在共享数据库、共享模式、共享表的方法中实现多租户。并用tenantid标记每个db行。 我已经重写了我的应用程序,所以管理者和DAO将把tenantId作为一个参数,只为正确的数据库资源服务。 当获取信息时,这对所有视图来说都是完美的。也用于创建新的东西(使用登录的用户t

  • 我正在将当前的应用程序迁移到多租户体系结构。由于只有一个代码库,我需要解决多个租户的问题。我使用的是单数据库、多模式的方法。每个租户将被分配一个单独的模式,其中元数据保存在默认模式中。 应用程序是用ASP构建的。NET MVC。我使用Dapper连接到我的SQL Server。我有50个函数,使用直接查询和存储过程调用数据库。当为每个租户初始化dapper时,是否有任何方法可以在不改变函数的情况下

  • 我目前正试图找出为我的系统设置多租户的最佳方法。我面临的问题是,租户并不总是必须是子域,但可以作为子域的一部分进行设置,子域可以有多个租户。我似乎在网上找不到任何东西可以帮助我在Laravel 6中进行设置。 系统要求: 一台服务器可以有许多子域 系统必须设置一个数据库,该数据库将使用tenant_id来确定哪些数据属于租户。 我目前正在以以下结构将所有子域数据存储在“subdomains”表中: