

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 决策矩阵
<a name="matrix"></a>

要决定应在 PostgreSQL 中使用哪种多租户 SaaS 分区模型，请查阅以下决策矩阵。矩阵分析了以下四个分区选项：
+ 思洛存储器 — 每个租户都有单独的 PostgreSQL 实例或集群。
+ 使用单独的数据库进行桥接 — 在单个 PostgreSQL 实例或集群中，每个租户都有一个单独的数据库。
+ 使用单独的架构进行桥接 — 在单个 PostgreSQL 数据库、单个 PostgreSQL 实例或集群中，每个租户都有单独的架构。
+ 池 — 单个实例和架构中租户的共享表。


****  

| **** | **筒仓** | **使用单独的数据库进行桥接** | **使用单独架构进行桥接** | **池** | 
| --- | --- | --- | --- | --- | 
| 使用案例 | 通过完全控制资源使用情况来隔离数据是一项关键要求，或者您的租户规模非常大，并且对性能非常敏感。 | 数据隔离是一项关键要求，并且需要对租户的数据进行有限的交叉引用，或者不需要交叉引用。 | 租户数量适中，数据量适中。如果您必须交叉引用租户的数据，则这是首选模型。 | 大量租户，每个租户的数据量较少。 | 
| 新租户入职敏捷性 | 很慢。（每个租户都需要一个新的实例或集群。） | 速度适中。（需要为每个租户创建一个新数据库来存储架构对象。） | 速度适中。（需要为每个租户创建一个新的架构来存储对象。） | 最快的选择。（需要最少的设置。） | 
| 数据库连接池配置工作量和效率 | 需要付出大量努力。（每个租户一个连接池。）<br />效率较低。（租户之间不共享数据库连接。）  | 需要付出大量努力。（除非您使用 [Amazon RDS 代理](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/rds-proxy.html)，否则每个租户只能配置一个连接池。） <br />效率较低。（租户和连接总数之间不共享数据库连接。 根据数据库实例类别，所有租户的使用量受到限制。） | 所需的精力更少。（所有租户都有一个连接池配置。） <br />效率适中。（仅在会话池模式下通过`SET ROLE`或`SET SCHEMA`命令重用连接。 `SET`使用 Amazon RDS 代理时，命令还会导致会话固定，但是为了提高效率，可以取消客户端连接池，并且可以为每个请求建立直接连接。） | 所需的精力最少。<br />效率最高。（所有租户都有一个连接池，所有租户都能高效地重复使用连接。 数据库连接限制基于数据库实例类别。） | 
| 数据库维护（[真空管理](https://www.postgresql.org/docs/current/routine-vacuuming.html)）和资源使用 | 更简单的管理。 | 中等复杂性。（可能会导致大量资源消耗，因为之后必须为每个数据库启动真空工作程序vacuum\_naptime，这会导致自动真空启动器 CPU 使用率过高。 清理每个数据库的 PostgreSQL 系统目录表可能还会带来额外的开销。） | 大型 PostgreSQL 系统目录表。（总pg\_catalog规模以十为单位 GBs，视租户数量和关系而定。 可能需要修改与吸尘相关的参数以控制表格膨胀。） | 表可能很大，具体取决于租户数量和每个租户的数据。（可能需要修改与吸尘相关的参数以控制表膨胀。） | 
| 扩展管理工作 | 大量工作（针对不同实例中的每个数据库）。 | 大量工作（在每个数据库级别）。 | 最少的工作量（在公共数据库中使用一次）。 | 最少的工作量（在公共数据库中使用一次）。 | 
| 更改部署工作 | 付出了巨大的努力。（连接到每个单独的实例并推出更改。） | 付出了巨大的努力。（Connect 连接到每个数据库和架构，然后推出更改。） | 适度的努力。（Connect 连接到公用数据库并发布每个架构的更改。） | 最少的努力。（Connect 连接到公共数据库并推出更改。） | 
| 变更部署-影响范围 | 最小。（单租户受到影响。） | 最小。（单租户受到影响。） | 最小。（单租户受到影响。） | 非常大。（所有租户都受到影响。） | 
| 查询绩效管理和工作量 | 可管理的查询性能。 | 可管理的查询性能。 | 可管理的查询性能。 | 维护查询性能可能需要花费大量精力。（随着时间的推移，由于表的大小增加，查询的运行速度可能会更慢。 您可以使用表分区和数据库分片来保持性能。） | 
| 跨租户资源影响 | 没有影响。（租户之间不共享资源。） | 影响适中。（租户共享公共资源，例如实例 CPU 和内存。） | 影响适中。（租户共享公共资源，例如实例 CPU 和内存。） | 冲击力很大。（租户在资源、锁冲突等方面相互影响。） | 
| 租户级调整（例如，为每个租户创建其他索引或为特定租户调整数据库参数） | 可能的。 | 有点可能。（可以对每个租户进行架构级别的更改，但数据库参数在所有租户中都是全局的。） | 有点可能。（可以对每个租户进行架构级别的更改，但数据库参数在所有租户中都是全局的。） | 不可能。（表格由所有租户共享。） | 
| 重新平衡对性能敏感的租户的工作量 | 最小。（无需重新平衡。 扩展服务器和 I/O 资源以应对这种情况。） | 中等。（使用逻辑复制或导pg\_dump出数据库，但停机时间可能会很长，具体取决于数据大小。 您可以使用 Amazon RDS for PostgreSQL 中的可传输数据库功能更快地在实例之间复制数据库。） | 中等，但可能涉及长时间的停机时间。（使用逻辑复制或导pg\_dump出架构，但停机时间可能会很长，具体取决于数据大小。） | 意义重大，因为所有租户共享相同的表。（对数据库进行分片需要将所有内容复制到另一个实例，并需要执行额外的步骤来清理租户数据。） <br />很可能需要更改应用程序逻辑。 | 
| 主要版本升级导致数据库停机 | 标准停机时间。（取决于 PostgreSQL 系统目录的大小。） | 停机时间可能会更长。（根据系统目录的大小，时间会有所不同。 PostgreSQL 系统目录表也会在数据库之间复制） | 停机时间可能会更长。（根据 PostgreSQL 系统目录的大小，时间会有所不同。） | 标准停机时间。（取决于 PostgreSQL 系统目录的大小。） | 
| 管理开销（例如，数据库日志分析或备份作业监控） | 重大努力 | 最少的努力。 | 最少的努力。 | 最少的努力。 | 
| 租户级别的可用性 | 最高。（每个租户都出现故障并独立恢复。） | 影响范围更大。（如果出现硬件或资源问题，所有租户都会失败并一起恢复。） | 影响范围更大。（如果出现硬件或资源问题，所有租户都会失败并一起恢复。） | 影响范围更大。（如果出现硬件或资源问题，所有租户都会失败并一起恢复。） | 
| 租户级别的备份和恢复工作 | 最少的努力。（可以独立备份和恢复每个租户。） | 适度的努力。（对每个租户使用逻辑导出和导入。 需要一些编码和自动化。） | 适度的努力。（对每个租户使用逻辑导出和导入。 需要一些编码和自动化。） | 付出了巨大的努力。（所有租户共享相同的桌子。） | 
| 租户级别的恢复工作 point-in-time | 最少的努力。（使用快照使用时间点恢复，或者在 Amazon Aurora 中使用回溯功能。） | 适度的努力。（使用快照恢复，然后使用导出/导入。 但是，这将是一个缓慢的操作。） | 适度的努力。（使用快照恢复，然后使用导出/导入。 但是，这将是一个缓慢的操作。） | 繁重的工作量和复杂性。 | 
| 统一架构名称 | 每个租户的架构名称相同。 | 每个租户的架构名称相同。 | 每个租户的架构不同。 | 通用架构。 | 
| 按租户自定义（例如，特定租户的其他表格列） | 可能的。 | 可能的。 | 可能的。 | 很复杂（因为所有租户共享相同的表）。 | 
| 对象关系映射 (ORM) 层的目录管理效率（例如 Ruby） | 高效（因为客户端连接是特定于租户的）。 | 高效（因为客户端连接是特定于数据库的）。 | 效率适中。（根据所使用的 ORM、 user/role 安全模型和search\_path配置，客户端有时会缓存所有租户的元数据，从而导致数据库连接内存使用率过高。） | 高效（因为所有租户共享相同的表）。 | 
| 合并租户报告工作 | 付出了巨大的努力。（您必须使用外部数据包装器 [FDWs] 来整合所有租户中的数据，或者提取、转换和加载 [ETL] 到另一个报告数据库。） | 付出了巨大的努力。（您必须使用 FDWs 将所有租户或 ETL 中的数据整合到另一个报告数据库中。） | 适度的努力。（您可以使用并集来聚合所有架构中的数据。） | 最少的努力。（所有租户数据都在同一个表中，因此报告很简单。） | 
| 用于报告的租户专用只读实例（例如，基于订阅） | 最少的努力。（创建只读副本。） | 适度的努力。（您可以使用逻辑复制或 AWS Database Migration Service [AWS DMS] 进行配置。） | 适度的努力。（您可以使用逻辑复制或 AWS DMS 进行配置。） | 很复杂（因为所有租户共享相同的表）。 | 
| 数据隔离 | 最好。 | 更好。（您可以使用 PostgreSQL 角色管理数据库级别的权限。） | 更好。（您可以使用 PostgreSQL 角色管理架构级别的权限。） | 更糟糕的是。（由于所有租户共享相同的表，因此必须实现诸如行级安全 [RLS] 之类的功能以实现租户隔离。） | 
| 租户特定的存储加密密钥 | 可能的。（每个 PostgreSQL 集群都可以有 AWS Key Management Service 自己的AWS KMS[] 密钥用于存储加密。） | 不可能。（所有租户共享相同的 KMS 密钥进行存储加密。） | 不可能。（所有租户共享相同的 KMS 密钥进行存储加密。） | 不可能。（所有租户共享相同的 KMS 密钥进行存储加密。） | 
| 使用 AWS Identity and Access Management (IAM) 对每个租户进行数据库身份验证 | 可能的。 | 可能的。 | 可能（通过为每个架构设置单独的 PostgreSQL 用户）。 | 不可能（因为所有租户共享表）。 | 
| 基础设施成本 | 最高（因为没有共享任何内容）。 | 中等。 | 中等。 | 最低。 | 
| 数据重复和存储使用情况 | 所有租户中总量最高。（PostgreSQL 系统目录表以及应用程序的静态和常用数据在所有租户之间复制。） | 所有租户中总量最高。（PostgreSQL 系统目录表以及应用程序的静态和常用数据在所有租户之间复制。） | 中等。（应用程序的静态和公共数据可以位于通用架构中，并可由其他租户访问。） | 最小。（没有数据重复。 应用程序的静态数据和公共数据可以位于同一个架构中。） | 
| 以租户为中心的监控（快速找出哪个租户导致了问题） | 最少的努力。（由于每个租户都是单独监控的，因此可以很容易地检查特定租户的活动。） | 适度的努力。（由于所有租户共享相同的物理资源，因此您必须应用额外的筛选来检查特定租户的活动。） | 适度的努力。（由于所有租户共享相同的物理资源，因此您必须应用额外的筛选来检查特定租户的活动。） | 付出了巨大的努力。（由于所有租户共享包括表在内的所有资源，因此您必须使用绑定变量捕获来检查特定 SQL 查询属于哪个租户。） | 
| 集中管理和 health/activity 监控 | 重大努力（建立中央监视和中央指挥中心）。 | 工作量适中（因为所有租户共享同一个实例）。 | 工作量适中（因为所有租户共享同一个实例）。 | 工作量最少（因为所有租户共享相同的资源，包括架构）。 | 
| 对象标识符 (OID) 和交易 ID (XID) 环绕的可能性 | 最小。 | 高。（因为 OID，XID 是一个单个 PostgreSQL 集群范围的计数器，因此在物理数据库之间进行有效清理可能会出现问题）。 | 中等。（因为 OID，XID 是一个单个 PostgreSQL 集群范围的计数器）。 | 高。（例如，单个表可以达到 TOAST OID 上限 40 亿，具体取决于 out-of-line列数。） | 