Schema-per-tenant 多租户模式
[!tip] 一句话理解 所有租户共享同一个数据库实例,但每个租户拥有独立的 Schema(模式),在”成本效率”与”数据隔离”之间取得平衡。
它是什么
Schema-per-tenant 是多租户 SaaS 应用中的一种数据隔离架构模式。它介于两种极端方案之间:
| 方案 | 隔离粒度 | 典型比喻 |
|---|---|---|
| Shared Schema(共享表) | 行级隔离(tenant_id 列) | 所有人住一间大通铺 |
| Schema-per-tenant(每租户一个模式) | 模式级隔离 | 每人一间独立卧室,共用一栋楼 |
| Database-per-tenant(每租户一个数据库) | 实例级隔离 | 每人一栋独立别墅 |
在 Schema-per-tenant 模式下,每个租户的数据存储在同一个数据库实例中各自独立的 Schema 里。所有租户的表结构相同(或可定制),但数据天然物理隔离——不同 Schema 下的同名表互不干扰。
核心原理
1. 隔离机制
每个租户对应数据库中的一个独立 Schema(如 PostgreSQL 的 schema、MySQL 的 database)。应用层在建立连接时,根据当前租户身份切换到对应的 Schema:
-- PostgreSQL 示例:切换 Schema
SET search_path TO tenant_abc;
-- 之后的所有 SQL 操作都在 tenant_abc 的表上执行
SELECT * FROM orders; -- 实际查询 tenant_abc.orders
应用层通常通过中间件或连接池配置,在请求入口处解析租户标识(如域名、Header、JWT claim),然后动态设置 Schema 路径。
2. Schema 管理策略
| 策略 | 说明 | 适用场景 |
|---|---|---|
| 模板克隆 | 新租户注册时,从模板 Schema 复制一套表结构 | 表结构统一、租户量大 |
| 迁移脚本 | 使用 Flyway/Liquibase 等工具统一管理所有 Schema 的版本迁移 | 需要频繁变更表结构 |
| 动态 SQL | 运行时拼接 Schema 名到 SQL 中 | 灵活但需防 SQL 注入 |
3. 跨租户查询
由于数据分散在不同 Schema 中,跨租户的聚合查询需要特殊处理:
- UNION ALL 方案:动态拼接所有租户 Schema 的查询,用 UNION ALL 合并结果
- 汇总表:单独维护一张公共 Schema 下的汇总表,通过定时任务或 CDC 同步
- 外部分析管道:将数据同步到数据仓库(如 BigQuery、ClickHouse)做跨租户分析
4. 连接池与资源管理
每个 Schema 不需要独立的连接池——它们共享同一个数据库实例。但需注意:
- 连接上下文切换:每个连接需要在请求开始时设置
search_path,请求结束时重置 - Schema 数量上限:PostgreSQL 等数据库在 Schema 数量过多时(数千个),
pg_catalog查询会变慢 - 资源竞争:所有 Schema 共享同一实例的 CPU、内存、IO,需要监控和限流
与相关概念的关系
[!info] vs 多租户 Shared Schema 模式 Shared Schema 在同一张表中用
tenant_id列区分租户,成本最低但隔离最弱——一个 SQL 注入 bug 就可能泄露所有租户数据。Schema-per-tenant 天然隔离,不需要在每条查询中加WHERE tenant_id = ?,但管理成本更高(Schema 迁移需要遍历所有租户)。
[!info] vs Database-per-tenant Database-per-tenant 隔离最强,甚至可以为不同租户配置不同的数据库版本/参数,但成本最高(每个实例都要独立运维)。Schema-per-tenant 共享实例资源,运维成本显著更低。
[!info] 与 索引 的关系 每个 Schema 的表独立维护索引,索引大小与单租户数据量成正比,不会因共享表导致索引膨胀。但大量 Schema 的索引总量仍会消耗实例级的内存和存储。
典型应用场景
- B2B SaaS 平台 — 不同企业客户需要强数据隔离以满足合规要求(如金融、医疗行业),同时希望控制基础设施成本
- 中等规模多租户应用 — 租户数量在几十到几百之间,既不想承担每租户一个数据库的成本,又需要比共享表更强的隔离
- 需要租户级定制 — 不同租户可能需要增加自定义字段或表,Schema-per-tenant 允许在不影响其他租户的情况下扩展单个 Schema
- 合规与审计 — 某些行业法规要求数据物理隔离(而非逻辑隔离),Schema-per-tenant 在同一实例内提供了这一保障
关联笔记
- 索引 — Schema 级别的索引管理
- 元数据驱动架构 — 多租户场景下的元数据管理
- 企业服务总线(ESB) — SaaS 集成场景中的数据隔离考量