因为专注所以专业
助力成长与创新,汇集前沿程序开发观点

客户A登录后刷出了客户B的订单,共库加租户字段能马上堵住吗?

2026年9月21日 阅读:91

结论先说:多租户串数据通常不是数据库自己出错,而是租户上下文在某个入口丢了。按 2026 年常见交付经验,租户数在几十到几百、单租户数据量不大时,共库共表加租户 ID 列是常见起点,但要同时配三道防线:服务端绑定租户上下文、数据访问层强制拼接租户条件、库层用带租户 ID 的唯一索引兜底。少一道,串数据风险就会明显上升。出现合同或监管要求物理隔离、单租户数据量明显高于其他租户、或需要按租户单独恢复时,再往独立 schema 或独立库走。

串数据多数不是数据库的锅

数据库只执行你给出的语句。语句里没有租户条件,它就会把整张表返回;问题出在写语句的人和生成语句的封装层。漏点分散在不同模块,演示环境数据少时不容易暴露,往往等两个租户数据攒起来、名称又相近才被客户截图发现。

  • 查询漏带租户条件:新报表 SQL、临时导出语句较容易赶工跳过。
  • 写入没写租户 ID:批量导入、手工补数据、后台新建记录时,租户列被留空或带上一个租户的值。
  • 唯一约束没带租户 ID:手机号、编码等全局唯一约束,会让 A 占用 B 的名额,表现为“没人用却提示重复”。
  • 缓存或会话 key 没带租户:字典、配置、权限缓存被另一租户覆盖,A 登录后看到 B 的配置。
  • 异步任务没切换上下文:定时跑批、消息消费复用线程时残留上一个租户的上下文,事后较难复盘。

先加租户字段还是拆库:三档方案怎么比

把隔离形态按三档来切,是因为改造成本与隔离强度基本同向变化。下面的周期是经验区间,实际取决于历史数据规模、模块耦合度和是否要同时改发布流程。

  • 共库共表 + 租户 ID 列:改造经验区间多在 1~3 周。隔离强度依赖应用层,较容易漏条件;适合租户多、单租户数据量小、暂无物理隔离要求的场景。
  • 共库独立 schema:改造常见区间 1~3 个月。靠 schema 边界降低误操作概率,连接数和迁移脚本数量随租户数增长;适合租户数量可控、希望按租户做权限隔离的场景。
  • 独立库或独立实例:隔离强度较高,可按租户单独备份和恢复;运维、监控、发版都要按租户维度拆分,租户越多边际成本越高;适合有合同或监管要求、或单租户数据量明显偏大的场景。

选择顺序按三件事排:有没有明确的物理隔离要求;单租户数据量与峰值是否显著高于其他租户;出问题后能否接受按租户单独恢复。三问里只要有一条答案是“需要”,就值得从共库往独立形态走一步。现实中也可混合:把数据量大或有单独合规要求的租户放到独立库,其余仍共享;路由规则统一收在数据源层,跨租户统计走离线汇总。

真正兜底的是三层:上下文、访问层、库层

按这三层分,是因为它们防的是三类不同问题:第一层防内部人员越权,第二层防开发写漏,第三层防前两层同时失效。只做其中一层,都会留下可复现漏洞。

  1. 第一层,租户上下文只从服务端取。登录成功后把租户 ID 写进会话或令牌,业务代码不把请求参数、请求头里的租户 ID 当取数依据;参数里的值只做一致性校验,对不上就拒绝。
  2. 第二层,数据访问层强制拼接。在 ORM 拦截器或统一查询封装中自动追加租户条件,并保留一个需要审批的绕过开关;绕过时记录操作人、租户和原因,便于事后核对。
  3. 第三层,库层兜底约束。把唯一索引改成带租户 ID 的联合唯一;跨租户强外键尽量不建,或只做弱校验。合规要求高的场景,可评估数据库自带的行级安全策略,但要先确认版本与运维能力支持,不要只写在方案里。

判断做没做到位,有个简单口径:随机抽五个查询接口,去掉业务代码里的租户条件,看是否仍然只返回当前租户数据。去掉就串,说明拦截层没有真正兜住。

一段交付现场经验:在一个多组织后台改造里,常见约束是历史数据几百万行、要求两三周上线,预算不支持一上来拆库。做法是先共库加租户 ID,在数据访问层强制拼接,并补一轮跨租户越权回归。结果是按期上线,代价是回归阶段多花约一周;如果省掉这轮测试,后续靠客户反馈发现串数据,返工量通常更大。

适用与不适用边界

适用:SaaS 产品、多分公司或多门店共用一套后台、多品牌共用系统且数据不能互看。判定核心是存在两个及以上客户,他们的数据本就不应互相可见。

不适用:租户其实是同一公司内部部门,本质是数据权限问题,用角色加数据范围更合适;硬上租户隔离会让公共字典、跨部门审批变得别扭。系统只有一个使用方、数据本就应互相可见,也无需提前引入租户维度。

常见问题

租户 ID 能不能让前端传过来?

不建议。前端参数可篡改,租户 ID 应由服务端在登录态里绑定;参数里的值只做一致性比对,不匹配就直接拒绝请求。

缓存 key 不带租户会出什么事?

同一个 key 会被后访问的租户覆盖,出现 A 看到 B 的配置或权限。常见做法是 key 统一加租户前缀,并给上下文设置合理超时。

共库共享表能不能过合规检查?

常见可以,前提是访问有审计、租户间隔离有可核对证据。若合同或监管明确要求物理隔离,共享表就不满足,需要按租户独立库或独立实例。

只有一个大客户要求独立部署,要不要改整体架构?

不必全拆。混合模式更常见:把该租户单独放独立库或独立实例,其余仍共享,代价是路由和发布流程要能按租户区分。


如果正卡在这一步,建议先做一件事:把现有接口随机抽五条,去掉代码里的租户条件跑一遍,看会不会返回别人的数据。会串的,先补访问层拦截和带租户 ID 的唯一索引,再谈拆库;不会串的,说明拦截层已经起作用,可以按数据量和合规要求慢慢往独立形态演进。租户数少于几十、单租户数据量不大的系统,通常不必急着拆。

有类似的项目需求?
联系我们,获取一对一项目参考方案
获取方案
准备好开始了吗,
那就与我们取得联系吧!
13370032918
了解更多服务,随时联系我们
请填写您的需求
您希望我们为您提供什么服务呢
您的预算

微信二维码
扫码添加客服微信
专业对接各类技术问题
联系电话
13370032918 (金经理)
电话若占线或未接到、就加下微信
联系邮箱
349077570@qq.com
提交成功
感谢您的信任,我们会尽快与您联系!
为您推荐以下案例