首页/数据/NoSQL 速查/多租户隔离:独立库、独立集合与共享结构
选型与架构50 条

多租户隔离:独立库、独立集合与共享结构

三种隔离级别各有取舍:每租户独立库/索引隔离强但连接与运维开销大;独立集合/索引是折中;共享结构加 tenantId 成本低,但要全链路强制过滤并防噪音邻居。选择看租户数量、合规要求与租户间规模差异。

NoSQL 速查数据更新于 2026-10-13

多租户隔离怎么选

多租户的核心矛盾是隔离强度与运维成本:隔离越强,每个租户的连接、备份、升级与监控开销越大。实际选型通常按租户数量与规模差异来定:租户少且合规要求高,可以独立库;租户多且规模相近,用共享结构加 tenantId 更现实,中间档是独立集合或独立索引。三种方案都要在数据访问层强制注入租户条件。

隔离级别对照

方案隔离性代价
每租户独立库强,备份与恢复可按租户单独做连接池、监控、升级操作成倍增加
独立集合 / 独立索引中,可按租户精细管理集合与索引数量随租户增长,元数据压力上升
共享 + tenantId靠过滤条件与权限兜底必须在统一入口强制注入,并防热点租户

基本信息

主键设计共享结构下索引必须以 tenantId 为前缀,否则查询无法按租户裁剪
路由搜索引擎可用 routing 把同租户文档固定到同一分片组,减少查询扇出
权限数据库角色可按库或前缀授权,共享结构的隔离只能靠应用层保证
规模差异大租户可单独开索引或独立集群,避免拖累其他租户
合规要求数据驻留或物理隔离的场景直接选独立库

典型使用场景

  • SaaS 应用起步期:租户多规模小,共享结构加 tenantId 成本最低
  • 大客户单独立库:便于按合同约定做备份、恢复与性能保障
  • 日志与检索场景:按租户 routing 或独立索引,控制查询扇出
  • 租户级限流:热点租户占用配额时需要单独限速与告警
  • 租户数据导出与删除:独立结构下按库或索引操作,共享结构下按条件批量清理

共享结构示例(MongoDB)

共享结构示例(MongoDB)
// 索引以 tenantId 为前缀,查询才能按租户裁剪数据
 db.orders.find({ tenantId: "t42", status: "open" }).sort({ createdAt: -1 })
db.orders.createIndex({ tenantId: 1, createdAt: -1 })

// 视图兜底:把租户过滤固化成视图,供报表类工具使用
db.createView("orders_t42", "orders", [{ $match: { tenantId: "t42" } }])

// 接入层统一封装:租户条件由框架注入,业务代码不直接拼查询
搜索引擎侧用 routing 把同一租户的数据路由到少量分片上,能把一次查询的扇出从「全部分片」压缩到「一块分片」,效果通常比调大分片数更明显。
共享结构下最危险的不是性能而是越权:任何一处漏带 tenantId 的查询都是跨租户数据泄露,必须靠统一数据访问层强制注入并配自动化用例覆盖。

易错点

  • 漏带 tenantId 的查询直接跨租户读数据:接口层必须强制注入,单靠开发自觉无法保证
  • 索引未以 tenantId 为前缀:每个租户的查询都要扫全表再过滤,租户越多整体越慢
  • 单个大租户的写入与外发拖垮共享集群(噪音邻居):需要按租户限流、配额与容量隔离
  • 按租户建集合或索引但不治理数量:元数据与代理由此膨胀,运维操作时长显著增加

数据来源与参考

  • MongoDB Manual: Multi-tenancy
  • Elasticsearch Guide: Routing
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌