博客 · 11 min 阅读

多租户 SaaS 中的锚定式身份:当一个人身兼多种角色

一位转为员工的客户,或一位转为客户的企业主,仍然是同一个人——系统必须知道这一点。
作者 · 发布于

案例研究 · 平台工程。Meta Dados 方法论(Genba · Kanso · Omotenashi)。

摘要。在服务领域的多租户 SaaS 中,同一个人会以客户、员工和企业主的身份出现——有时还分布在多个门店中。我们将这一问题建模为锚定式身份图:一个全局实体(即由 CPF 锚定的个人),多个按租户去范式化的关联关系向其汇聚。一项受控实验在生产数据库上以 ROLLBACK 事务方式执行,结果表明身份能够通过 CPF 正确统一,但去范式化的数据会在各表之间悄然发生偏离,而某一类以空 CPF 创建“内联”登录账号的入口,会将一个人分裂成两个身份。我们描述了两项已验证的干预措施,并推导出可复用的原则。

1. 引言

预约类平台将三种实体视为一等公民——客户、员工和门店——每一种都有其自然键:客户以电话号码识别;员工要求提供 CPF;门店以 CNPJ + 电子邮箱识别(个体从业者则以 CPF 识别)。问题在于这三者并非互斥:一位客户可能被聘用而成为员工;一位客户可能自己开店创业;一位企业主可能作为客户去另一家沙龙预约。系统需要让信息在各表之间流转并保持一致,避免同一关键数据在不同记录中相互偏离。

我们以Marcaê平台作为案例研究,但该模型与研究结论具有普遍性:适用于任何一个个体随时间推移、跨租户承担异质角色的 SaaS。

2. 模型:锚定式身份

核心思想是将身份角色分离。个人是一个全局实体——不属于任何租户,由一个强键(规范化后的 CPF)锚定。每一条关联关系(客户、员工、用户)都携带一份关键字段的去范式化副本,以及一个指向该个人的外键 person_id。一个数据库触发器(vincular_pessoa_por_cpf)执行查找或创建:在写入一条带有效 CPF 的关联关系时,它会关联(或创建)该 CPF 对应的个人并固定 person_id。若没有有效的 CPF,身份即局限于该租户

门店 A门店 B客户员工企业主客户个人唯一 CPF · 锚点姓名 · 邮箱 · 电话无 CPF → 身份局限于租户
锚定式身份图:来自多个租户的关联关系通过 person_id 汇聚(fan-in)到唯一的个人。若无 CPF,关联关系将孤立于该租户内。

3. 不变式与偏离度指标

该模型必须保证两个不变式。第一个是身份统一(I1):两条具有相同有效 CPF 的关联关系指向同一个人。第二个是角色完整性(I2):该个人知晓由其关联关系派生出的所有角色(租户 + 角色)。

为衡量关键数据(姓名、电子邮箱、电话)的一致性,我们定义了一个偏离率 δ:在锚点及其关联关系之间,某个关键字段存在多个非空值的个人所占比例。δ = 0 是目标——个人是唯一的真相来源。

4. 身份分裂缺陷

有一类入口在(连同客户一起)“内联”创建登录账号时,采用了一种忽略 CPF 的锚定方式——实际上,它总是创建一个新的个人。如果一个人经过了一个执行锚定的入口,又经过了一个不执行锚定的入口,那么他就会被两个个人所表示——从而违反 I1。分裂率 σ 随着不执行锚定的入口的使用而成比例增长。这是严重性最高的缺陷,因为身份一旦分裂,就只能通过人工/SQL 操作来重新对齐。

5. 方法论与结果

我们采用 Genba——深入现场:不去推演预期中的模型,而是运行真实模型。有两种技术:(1)穷尽式地阅读产生或转化客户/员工/用户/企业主的 15 个入口,记录每个入口写入什么、是否基于 CPF 锚定;(2)事务化模拟——我们直接在生产数据库中、于 BEGIN … ROLLBACK 内实例化各种身份历程:锚定触发器会真实触发,但不会持久化任何内容。

结果印证了该模型,并标出了它失效之处:

6. 干预措施

将去重作为等价关系。旧规则仅凭电话号码就合并两份记录;新规则要求规范化后的电话号码与姓名同时匹配。这样,共用一个电话号码的两个不同的人(用自己的手机为孩子预约的母亲)就不会再被错误地合并。

将合并作为逐字段的 fold当两份记录确实属于同一个人时,合并不再是“选一份、弃一份”,而是逐字段地取舍:一张差异表将每个存在偏离的字段并排呈现,由操作员选择保留在幸存记录中的值。顺序很重要——必须在应用取舍之前先重新挂接引用并归档被移除的记录——否则部分唯一索引会发生冲突。丢失数据的合并是一种倒退;逐字段的合并则保留每份记录中最优的内容。

7. 讨论与原则

该案例揭示了一个反复出现的权衡:在关联关系中去范式化关键字段,能让每个界面既快速又自足,代价是一致性;而将个人作为唯一真相来源则能消除偏离,代价是读取时的耦合。以下是适用于任何具有共享身份的多租户平台的可复用原则:

8. 结论

当存在 CPF 时,Marcaê 的身份能够正确统一——锚点有效,且对角色转变具有稳健性。那一类会导致身份分裂的入口已通过数据库触发器封堵(对齐机制确保账号跟随 CPF 对应的个人,合并不再产生孤立的登录账号,锚点也开始学习它此前缺失的关键数据)。剩下的只有完整的唯一真相来源——这是一项设计决策,而非缺陷。所带来的收益不仅是技术层面的:它保证了一位转为员工的客户,或一位转为客户的企业主,在整个系统中始终是同一个人。

我们在此集成的系统

常见问题

为什么不能只用电话号码来识别个人?

因为电话号码并不是识别个人的强键:两个不同的人会共用一个号码(用自己的手机为孩子预约的母亲),而一个人也会更换号码。以 CPF(强键,每人唯一)锚定,并仅将电话+姓名作为去重关系,可避免错误地合并不同的人。

这只适用于预约场景,还是适用于任何 SaaS?

该模型具有普遍性。它适用于任何一个个体随时间推移、跨租户承担异质角色的多租户 SaaS——市场平台、医疗、教育、物业管理平台等。“一个锚点,一个键;角色是状态,而非身份”这一原则可在各个领域间迁移;变化的只是强键和关键字段的集合。

免费开始

您的平台是否存在同一个人分散在互相偏离的多份记录中?48 小时内免费诊断。

我们梳理您现有的系统,指出最大的瓶颈,并交付按风险×工作量排序的方案。无论是否选择 Meta Dados,您都能获得清晰的方向。

获取我的诊断 → 通过 WhatsApp 联系 无需承诺,无需信用卡。
我们将在 2 个工作小时内回复。
←  Voltar para Blog