2. 多租户模型设计

多租户(Multi-Tenancy)是 SaaS 架构的核心特征。租户隔离模式直接决定了数据安全性、运维复杂度、扩展成本和查询性能。业界主流方案可归纳为三种:数据库隔离、Schema 隔离、共享表隔离。本章从隔离性、性能、成本、开发复杂度四个维度进行系统对比,并给出选型决策树。

2.1 三种隔离模式的定义与结构

核心原则:隔离级别越高,安全性和性能隔离越好,但资源成本和运维开销也越高。选型本质是在“安全合规”与“运营效率”之间做权衡。

模式一:数据库隔离(Database per Tenant)

每个租户拥有独立的数据库实例。数据在物理层面完全隔离,一个租户的故障或慢查询不会影响其他租户。

  • 适用场景:金融、医疗、政府等高合规行业;租户数量少(通常 < 200)但单租户数据量大。
  • 优点:最强数据隔离;备份与恢复粒度细;可针对不同租户独立扩缩容。
  • 缺点:连接数随租户线性增长;跨租户聚合查询困难;运维成本高。

模式二:Schema 隔离(Schema per Tenant)

所有租户共享同一个数据库实例,但每个租户拥有独立的 Schema(命名空间)。表结构相同,数据按 Schema 逻辑隔离。

  • 适用场景:中型 SaaS 平台(租户数 200–5000);需要一定隔离性但希望控制数据库实例数量。
  • 优点:隔离性较好;共享数据库连接池;跨租户查询可通过跨 Schema 实现。
  • 缺点:单实例资源争用;Schema 数量过多时元数据管理复杂;迁移租户需 DDL 操作。

模式三:共享表隔离(Shared Table with Tenant ID)

所有租户共享同一套表结构,通过 tenant_id 列区分数据行。这是最经济的模式,也是实现最复杂的模式。

  • 适用场景:超大规模 SaaS(租户数 > 5000);单租户数据量小;对隔离性要求较低。
  • 优点:资源利用率最高;运维简单;跨租户分析查询方便。
  • 缺点:数据隔离最弱;必须依赖应用层和 SQL 过滤保证安全;索引和查询复杂度高。

2.2 核心维度对比表

对比维度 数据库隔离 Schema 隔离 共享表隔离
数据隔离级别 物理隔离(最高) 逻辑隔离(中) 行级隔离(低)
单租户故障影响 不影响其他租户 可能影响同实例租户 可能影响全表
备份与恢复 按租户独立备份 按 Schema 备份 全表备份,恢复粒度粗
跨租户查询 困难(需跨库) 较容易(跨 Schema) 最方便(加 tenant_id 条件)
数据库连接数 随租户线性增长 共享连接池 共享连接池
资源利用率 低 中 高
开发复杂度 低(天然隔离) 中(需动态 Schema 路由) 高(需强制 tenant_id 过滤)
典型租户规模 < 200 200 – 5000 > 5000

2.3 隔离模式架构对比图

下图从数据容器维度展示三种模式的物理与逻辑边界:

三种租户隔离模式架构对比 三种租户隔离模式架构对比 数据库隔离 租户 A 数据库 独立实例 / 独立连接 租户 B 数据库 独立实例 / 独立连接 租户 C 数据库 独立实例 / 独立连接 Schema 隔离 租户 A Schema 共享实例 / 独立命名空间 租户 B Schema 共享实例 / 独立命名空间 租户 C Schema 共享实例 / 独立命名空间 共享数据库实例 共享表隔离 共享表(含 tenant_id) | tenant_id | 字段1 | 字段2 | ... | A001 | xxx | yyy | ... | B002 | xxx | yyy | ... | C003 | xxx | yyy | ... | A001 | zzz | www | ... | B002 | zzz | www | ... 行级隔离

2.4 选型决策树

实际项目中,选型通常不是“非此即彼”,而是根据租户特征分层组合。以下决策树可帮助快速定位:

多租户隔离模式选型决策树 多租户隔离模式选型决策树 租户隔离需求评估 高合规要求? 低合规要求? 数据库隔离 租户数 < 200 共享表隔离 租户数 > 5000 Schema 隔离 租户数 200–5000 混合策略: 高合规租户独立库 混合策略: 中型租户 Schema 混合策略: 小型租户共享表 💡 选型建议 大型 SaaS 通常采用混合模式:高价值租户独立库 + 普通租户 Schema + 免费租户共享表

2.5 混合模式实战案例

以某企业级 CRM SaaS 平台为例,其租户分层策略如下:

租户层级 隔离模式 租户数量 数据量/租户 路由标识
企业版 数据库隔离 50 > 500 GB shard_id → 数据库连接
专业版 Schema 隔离 2000 50 – 500 GB schema_name → 实例内路由
免费版 共享表隔离 30000 < 5 GB tenant_id → SQL 过滤
工程要点:混合模式下,应用层需要实现 多级租户路由。建议在 API 网关或 ORM 拦截器中统一注入租户上下文,根据租户等级动态选择数据源或 Schema。后续章节将详细讲解路由拦截链路的实现。

2.6 选型避坑清单

  • 不要过早优化:初期租户数少时优先选择 Schema 隔离,后期再根据增长曲线迁移部分租户到独立库。
  • 避免“全共享”陷阱:共享表隔离虽然成本低,但一旦出现 SQL 注入或 tenant_id 过滤遗漏,将导致全平台数据泄露。
  • 备份策略差异:数据库隔离模式下,备份脚本必须遍历所有数据库;共享表模式下需考虑增量备份对全表锁的影响。
  • 连接池配置:数据库隔离模式需要为每个租户维护独立连接池,建议使用 HikariCP 动态连接池组管理。
  • 跨租户查询:如果业务需要频繁跨租户分析(如 BI 报表),共享表隔离是最优选择,但必须配合行级安全策略(RLS)。
安全红线:无论选择哪种隔离模式,永远不要在应用层信任 tenant_id。租户标识必须从认证 Token 中解析,禁止从请求参数或请求体中读取。这是多租户安全的第一原则。