3. 多租户数据隔离策略选型
多租户医疗SaaS的数据隔离策略,本质上是在隔离强度、资源成本、运维复杂度、合规可证明性四个维度之间做权衡。医疗场景的特殊性在于:数据一旦泄露,后果不仅是商业损失,还涉及《个人信息保护法》《数据安全法》以及等保2.0对医疗健康数据的分类分级要求。因此选型不能只看技术便利,必须先回答“这份数据最坏情况下被谁看到会造成什么后果”。
三种隔离模式的工程实质
独立数据库(Database per Tenant):每个租户一套独立数据库实例或独立物理库,连接串、账号、备份策略完全分离。优点是故障域、性能域、备份恢复域天然隔离,单租户的大查询不会拖垮其他租户;缺点是实例数量随租户线性增长,连接池、监控、版本升级、Schema迁移都要按租户维度编排。适合三级医院、区域影像中心、体检连锁总部这类租户数量有限但数据极敏感、SLA要求高的客户。
共享数据库独立Schema(Schema per Tenant):同一数据库实例内,每个租户一个Schema,表结构相同。它保留了“逻辑上独立命名空间”的清晰边界,权限可以按Schema授予,备份可以按Schema导出。相比独立库,实例数大幅下降,但单实例内的资源争抢仍然存在,且当租户数达到数百时,Schema数量会让元数据管理和DDL变更变得沉重。适合中型连锁诊所、区域医共体等租户数量中等、敏感度较高的场景。
共享数据库共享Schema加租户ID(Shared Schema with Tenant ID):所有租户共用同一套表,通过tenant_id列区分数据行。资源利用率最高、运维最简单、扩容最平滑,但隔离完全依赖应用层和数据库层的访问控制。任何一处SQL漏写tenant_id条件,都可能造成跨租户数据泄露。适合小微诊所、单体门店、SaaS试用租户等数量大、单租户数据量小、敏感度相对可控的场景。
医疗数据敏感度如何影响隔离级别
医疗数据不能笼统地按“患者信息”一刀切。工程上通常按可识别性 + 临床后果 + 合规约束做三级划分:
- 高敏感:诊断结论、影像原始数据、基因测序、传染病报告、精神科记录。这类数据一旦跨租户泄露,可能造成歧视、保险拒保等不可逆后果,且等保三级明确要求“重要数据独立存储、访问可审计”。建议独立数据库,并对关键字段做应用层加密(如AES-256-GCM),密钥按租户托管在KMS中。
- 中敏感:处方、检验结果、费用明细、住院记录。它们能关联到具体患者,但通常需要结合其他信息才能造成严重危害。独立Schema是较稳妥的折中,配合数据库行级安全策略(RLS)和按Schema的权限授予。
- 低敏感:医生排班、科室公告、药品字典、收费项目字典。这些数据跨租户泄露影响有限,可以放在共享Schema中,但仍需
tenant_id过滤,避免“串号”造成业务混乱。
选型决策框架
面对一个具体租户或一类数据域,建议按以下顺序判断,而不是先选技术:
- 合规底线:该数据是否属于等保三级或行业监管明确要求独立存储的范围?若是,直接进入独立数据库,不再往下比较成本。
- 租户规模与增长:预计租户数在50以内且单租户数据量大,独立库的运维成本可接受;租户数数百以上,独立Schema或共享Schema更现实。
- 故障与性能隔离要求:是否存在单租户批量导入、影像调阅等重负载操作?若有,独立库或独立Schema能避免“一个租户拖垮全部”。
- 团队运维能力:独立库需要自动化 provisioning、连接池管理、按租户迁移工具;如果团队没有相应平台能力,强行上独立库会带来更高的线上风险。
- 成本与SLA:独立库的数据库实例费用、备份存储费用、跨可用区部署费用都要计入报价模型,不能只算开发成本。
一个可落地的判断规则是:高敏感数据域 + 租户数可控 → 独立数据库;中敏感数据域 + 租户数中等 → 独立Schema;低敏感数据域 + 租户数大 → 共享Schema加tenant_id,并强制RLS兜底。对于混合型SaaS,完全可以采用“核心库独立 + 辅助库共享”的混合架构,而不是三选一。
共享Schema下的关键防护
如果最终选择共享Schema,必须把tenant_id从“约定”升级为“强制”。推荐做法:在数据库层为每张业务表启用行级安全策略,例如 PostgreSQL 中:
ALTER TABLE patient_record ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON patient_record
USING (tenant_id = current_setting('app.current_tenant')::uuid);
-- 应用连接建立后执行:
SET app.current_tenant = '8f3c...e21';
这样即使应用层某条SQL漏写tenant_id,数据库也会自动过滤。同时,所有跨租户查询必须走单独的审计通道,记录操作人、租户、时间、SQL指纹,便于事后追溯。对于医疗SaaS,建议把“租户上下文注入”做成框架级拦截器,禁止业务代码直接拼接tenant_id,从源头降低越权风险。
tenant_id不能只靠开发者自觉。必须同时具备:数据库RLS、应用层拦截器、集成测试中的跨租户越权用例、以及生产环境的慢查询与异常访问告警。四者缺一,隔离就只是纸面承诺。选型没有绝对最优,只有与租户结构、数据敏感度、团队能力和合规要求最匹配的组合。把上述判断顺序固化成评审清单,每次新租户接入或新数据域上线时逐项确认,才能避免“先上线、后补隔离”带来的返工与合规风险。