返回模板页

SaaS 多租户数据库 Schema 示例

以下多租户示例展示了同样的租户-用户-资源核心如何随隔离策略变化——纯共享 schema、每租户 schema、企业级混合,以及租户即个人工作区的 B2C 变体。

SaaS 多租户数据库 Schema 示例

真实案例

共享 schema 加 tenant_id(默认)

使用场景: 构建首个 B2B SaaS 的开发者

一个 Postgres 数据库,一个 schema
每张业务表都有非空的 tenant_id 列
行级安全策略强制隔离
订阅、套餐和审计日志均按 tenant_id 划分
备份和迁移一次应用于所有租户

这样组织的原因: 共享 schema 是最简单也最便宜的多租户模式——一个数据库、一套表,到处用 tenant_id 做隔离。图表的职责是确保没有业务表漏掉 tenant_id——这是跨租户数据泄漏最常见的原因。

每租户独立 schema

使用场景: 有合规或大客户隔离需求的团队

一个数据库,每租户一个 schema
Tenant 表位于 public/control schema
租户 schema 内部没有 tenant_id 列
迁移分别应用到每个 schema
更强的隔离,以运维复杂度为代价

这样组织的原因: 每租户 schema 用运维简便换取更强隔离——图表去掉业务表上的 tenant_id,因为 schema 本身就是边界,适合监管行业或非常大型的企业客户。

混合模式(默认共享,企业隔离)

使用场景: 既有小客户也有企业客户的 SaaS

多数租户位于共享 schema,用 tenant_id
企业级享有独立 schema 甚至独立数据库
Tenant 上的 placement 列指向正确后端
路由层读取 placement 选连接
迁移跑两次:共享一次,每企业 schema 一次

这样组织的原因: 混合让你能起步便宜、对特定客户升级——图表在 Tenant 上加入 placement 列,把查询路由到共享 schema 或独立 schema,让数据主权类需求有出路,无需从第一天就重构。

带工作区的 B2C

使用场景: 每个用户拥有自己工作区的消费级 SaaS

Tenant 变成「Workspace」或「Account」,通常每用户一个
Membership 仍存在,用于共享/团队工作区
免费 vs 付费套餐驱动订阅状态
所有资源按 workspace_id 划分
注册时自动创建个人工作区

这样组织的原因: B2C SaaS 常复用多租户骨架,把 Tenant 重命名为 Workspace,并在注册时自动创建一个——图表仍把工作区作为隔离边界,为日后加入团队套餐留好门,无需重构。

使用技巧

  • 在每张业务表上都加 tenant_id,而不只在顶层——没有 tenant_id 校验的跨行连接是跨租户泄漏的方式。
  • 把 User 做成全局,把 Membership 作为租户关联——一个邮箱的用户应能属于多个租户。
  • 订阅挂在 Tenant 而非 User 上;计费是按组织而非按人。
  • 在 Postgres 加行级安全策略(或应用层等价物),让漏掉 WHERE 子句也无法返回其他租户的数据。

在线开始编辑

回到模板页,直接替换成你的课程主题、章节和复习重点,就可以继续使用这套结构。

使用这个模板: /editor/new?template=saas-multi-tenant-database-schema

编辑此多租户 schema 模板