2. 多租户数据隔离模式选型

多租户系统的数据隔离模式,本质上是在“隔离强度”与“资源效率”之间做取舍。业界最常用的三种模式是:独立数据库(Database per Tenant)、共享数据库独立 Schema(Schema per Tenant)、共享数据库共享 Schema(Shared Schema)。它们并不是简单的“好与坏”排序,而是分别适配不同的租户规模、合规要求、成本预算和运维能力。选型的核心不是记住三种模式的名称,而是理解每种模式在连接、命名空间、数据行、权限和扩展路径上的真实差异,并能根据业务约束做出可解释的决策。

三种模式的真实结构差异

独立数据库模式下,每个租户拥有一个独立的数据库实例或独立数据库。应用层通过租户标识路由到对应连接串,租户之间的表结构、索引、备份、恢复完全独立。它的隔离级别最高,单租户故障不会波及其他租户,也最容易满足数据驻留和合规审计要求。代价是连接数、实例数、备份任务和升级脚本随租户数量线性增长,资源利用率低,小租户会浪费大量空闲容量。

共享数据库独立 Schema 模式中,所有租户共用一个数据库实例,但每个租户拥有独立的 Schema(在 PostgreSQL 中即独立命名空间,在 MySQL 中通常用“独立数据库名”模拟)。应用连接同一个实例,通过 search_path 或表名前缀切换到目标租户的 Schema。它保留了较强的逻辑隔离,表结构可以按租户独立演进,备份和迁移可以按 Schema 粒度进行,同时实例资源被多个租户共享,成本明显低于独立数据库。它的主要风险是单实例成为共享故障域,且当租户数量达到数千时,Schema 数量会带来元数据管理和连接池压力。

共享数据库共享 Schema 模式中,所有租户的数据存放在同一组表中,通过 tenant_id 列区分归属。应用每次查询都必须带上租户过滤条件,通常配合行级安全策略(RLS)或数据访问层强制注入。它的资源效率最高,运维最简单,适合海量小租户场景。但隔离最弱,任何遗漏过滤条件的查询都可能造成跨租户数据泄露,且单表数据量会随租户总数增长,索引和分区设计需要更精细。

三种多租户数据隔离模式结构对比 隔离强度递减 · 资源效率递增 · 运维复杂度递减 独立数据库 租户 A DB_A · 独立连接串 租户 B DB_B · 独立连接串 租户 C DB_C · 独立连接串 隔离级别:物理级 故障域:单租户 备份粒度:整库 扩展方式:加实例 适用:大客户/合规 成本:高 运维:复杂 共享数据库 · 独立 Schema 共享数据库实例 Schema_A search_path = tenant_a Schema_B search_path = tenant_b Schema_C search_path = tenant_c 隔离级别:逻辑级 故障域:单实例 备份粒度:按 Schema 扩展方式:加 Schema 适用:中大型租户 成本:中 · 运维:中等 共享数据库 · 共享 Schema 共享数据库实例 共享 Schema · 公共表 orders 表 tenant_id | order_id | amount T_A | 1001 | 200 T_B | 2001 | 350 隔离级别:行级 故障域:全租户 备份粒度:整库 扩展方式:加节点/分区 适用:海量小租户 成本:低 · 运维:简单 隔离强度递减 → 资源效率递增

选型决策的关键维度

面对具体项目,可以从五个维度建立决策框架。第一是租户规模与数量:如果租户数量在几十个以内且单租户数据量大,独立数据库或独立 Schema 更合适;如果租户数量达到数千甚至数万,共享 Schema 几乎是唯一可运维的选择。第二是合规与数据驻留要求:金融、医疗等行业常要求数据物理隔离或指定地域存储,独立数据库最容易满足。第三是成本与资源利用率:独立数据库的实例成本随租户线性增长,共享 Schema 的边际成本最低。第四是运维与发布能力:独立数据库需要自动化 provisioning 和批量升级工具,独立 Schema 需要 Schema 迁移编排,共享 Schema 只需一次 DDL 但需要严格的数据访问层约束。第五是故障隔离与恢复目标:独立数据库可实现单租户精确恢复,共享 Schema 的恢复通常只能整库回滚,RPO/RTO 要求高的场景需要谨慎。

混合模式与渐进式演进

实际工程中很少全程只用一种模式。更常见的做法是混合模式:大客户使用独立数据库,中小客户使用共享数据库独立 Schema,长尾免费租户使用共享 Schema。这种分层策略可以在成本、隔离和运维之间取得平衡。另一种常见路径是渐进式演进:产品早期租户少、需求变化快,先用共享 Schema 快速迭代;当出现第一个要求独立部署的大客户时,再引入独立数据库;当租户数量增长到共享 Schema 的索引和分区难以支撑时,再迁移到独立 Schema。演进的关键是提前在数据访问层保留租户路由抽象,避免后期迁移时重写业务代码。

决策提示:不要试图用“哪个模式最好”来回答选型问题。正确的问法是:在当前租户规模、合规约束、成本预算和团队运维能力下,哪种模式的隔离强度刚好满足要求,同时资源效率和运维复杂度在可接受范围内。选型是一个约束满足问题,不是优劣排序问题。

一个可执行的决策检查表

下面给出一个可直接用于项目评审的决策检查表。使用时逐项回答,根据答案倾向选择模式。该表为示例性工具,具体阈值需结合团队实际情况调整。

检查项 倾向独立数据库 倾向独立 Schema 倾向共享 Schema
租户数量级 < 50 50 ~ 2000 > 2000
单租户数据量 TB 级 GB ~ TB MB ~ GB
合规要求 物理隔离/数据驻留 逻辑隔离/审计 无特殊要求
单租户恢复需求 必须支持 最好支持 可接受整库恢复
Schema 变更频率 低/按租户定制 中/可分批 高/统一变更
团队运维能力 强/有自动化平台 中/有迁移工具 基础/依赖云服务

以某 SaaS 工单系统为例:初期 200 个租户,单租户数据量约 2GB,无强合规要求,团队 3 人。按检查表,租户数量落在独立 Schema 区间,数据量适中,合规无特殊要求,运维能力中等,因此选择共享数据库独立 Schema。实现上使用 PostgreSQL,每个租户一个 Schema,应用连接池按租户缓存 search_path,DDL 变更通过迁移脚本遍历所有 Schema 执行。当租户增长到 3000 个时,再评估将长尾租户迁移到共享 Schema,大客户保留独立 Schema 或独立数据库。这个判断过程比直接套用“最佳实践”更可靠,因为它把约束显式化了。

常见误区:很多团队在共享 Schema 模式下只依赖应用层拼接 WHERE tenant_id = ?,而没有数据库层面的强制约束。一旦某个查询遗漏条件,就会造成跨租户数据泄露。建议在共享 Schema 模式下启用行级安全策略(RLS),或在数据访问层使用统一的租户上下文注入,并配合自动化测试覆盖所有查询路径。

总结来说,三种模式没有绝对优劣,只有是否匹配当前约束。独立数据库赢在隔离和合规,独立 Schema 赢在平衡,共享 Schema 赢在效率和规模。选型时先把租户规模、合规、成本、运维、恢复五个维度的约束写清楚,再用决策检查表逐项对照,最后用混合模式或渐进式演进保留调整空间。这样得到的方案才是可解释、可落地、可演进的。