用户体系建模:三户模型与三层身份模型

用户系统看似简单——不就是注册、登录、个人信息?但当业务复杂到一定程度(多业务线、多角色、资金账户、企业客户),"用户"这个概念会分裂成多个不同的实体,如果在设计初期没有想清楚它们之间的关系,后续的每一次业务扩展都会变成数据迁移的噩梦。

本文围绕两个核心模型展开:三户模型解决"交易类系统中,客户、用户、账户怎么建模"的问题;三层身份模型解决"认证和社交场景中,身份标识怎么分层"的问题。两者互补,共同构成用户体系的完整建模框架。


一、为什么需要系统化的用户体系建模

大多数系统在早期只有一张 user 表:ID、手机号、密码、昵称、头像。这在单一业务、单一角色的阶段足够用,但随着业务演进,问题逐步暴露:

阶段 出现的问题 根因
引入支付 用户表里硬塞了余额、银行卡字段,改一个字段要锁全表 没有把"资金账户"从"用户"中分离
引入企业客户 企业和个人混在一张表,权限模型混乱 没有区分"客户"和"用户"
引入多业务线 淘宝和天猫的用户数据互相打架,身份不统一 没有全局客户标识
引入第三方登录 微信登录和手机号登录关联不上同一个人 没有把"登录凭证"和"账户标识"分离
引入社交功能 昵称和登录账号耦合,改昵称影响登录 没有把"公开身份"和"登录身份"分离

三户模型和三层身份模型,分别从不同的角度解决了上述问题。 前者聚焦交易和资金场景,后者聚焦认证和社交场景。


二、三户模型

2.1 起源与核心思想

三户模型最早在增强型电信运营图(Enhanced Telecom Operations Map,eTOM)中提出,是电信行业营销模型转向"以客户为中心"理念的产物。近年来,金融行业和互联网行业也逐步采用了这一模型。

三户指三个相互关联但独立的实体,分别归属于不同的业务域:

实体 定义 归属域 核心关注
客户(Customer) 自然人或法人,现实世界中的主体 社会域 你是谁(身份)
用户(User) 客户在系统中的登录实体,使用业务的凭证 业务域 你能做什么(权限)
账户(Account) 客户的资金或资源账户,用于交易和结算 资金域 你有什么(资产)

核心关系:一个客户可以有多个用户,一个客户可以有多个账户。用户和账户之间是多对多——一个账户可以被多个用户操作(企业场景),一个用户也可以操作多个账户(零钱账户 + 银行卡账户)。

以电信业务为例:张三(客户)办理了一个手机 SIM 卡和一个宽带业务(两个用户/产品实例),共用一个缴费账户(账户)。也可以为手机和宽带各开一个独立账户。

以电商为例:张三(客户)用手机号 A 注册了淘宝(用户 A),又用手机号 B 注册了天猫(用户 B),两个用户通过实名认证(身份证归并)归属于同一个客户。张三有一个零钱账户和一个绑定的银行卡账户(两个账户)。

2.2 为什么要拆成三个实体

不拆的代价是什么?

如果不拆 后果
把客户信息和用户信息混在一起 一个人注册两个账号就产生两条"客户"记录,无法做客户级的统一分析
把用户信息和账户信息混在一起 余额字段和登录字段在同一张表,高频的登录操作和低频的资金操作互相影响
把三者全混在一起 企业客户的多人操作同一账户的场景无法建模

拆分的核心价值是关注点分离:客户关注"你是谁",这是法律和商业层面的实体;用户关注"你能做什么",这是系统和权限层面的实体;账户关注"你有什么",这是资金和资源层面的实体。三者的生命周期、变更频率、安全等级完全不同,放在一起必然互相掣肘。


三、客户(Customer)

3.1 个人客户

在银行体系中,一般是先有客户再有用户——柜台人员面签后在系统中建立客户对象。而在互联网体系中,一般是先有用户再有客户——用户先注册(只有手机号和密码),后续逐步补充身份信息(实名认证)。

客户的业务主键是证件号(身份证)。同一证件号在系统中只对应一个客户——当相同证件号从不同渠道进入系统时,需要执行客户归并:将多条记录合并到同一个客户 ID 下。归并是有风险的(万一证件号录入错误导致误合并),需要鉴权手段(如人脸识别、短信验证)来保障。

互联网系统中常用手机号作为客户识别的主键,但手机号存在注销和更换的问题,需要额外的归并和解绑机制。

客户的生命周期

客户生命周期

上图展示了客户从注册到禁用的完整状态流转。几个关键设计决策:

  • 没有"销户"状态:为了支持历史业务的追溯,客户一般不做物理删除,只做逻辑禁用
  • 支持"冻结"和"止付":以司法协查为例,客户被协查时需要冻结其下所有资金账户
  • 生命周期与账户联动:客户层面的状态变更会级联影响其下所有账户,因此客户的状态机设计要和账户的状态机保持一致

3.2 企业客户

企业客户的三户模型同样适用,但更复杂:

  • 企业客户是一个组织,其账户由组织授权内部人员(用户)去操作
  • 一般是多个用户操作一个或多个资金账户,通过角色管理(RBAC,Role-Based Access Control)实现授权
  • 企业客户的识别通过企业证件(营业执照统一社会信用代码),相同证件号归并到同一企业客户
  • 一个企业可以开通多个商户(商户是企业客户在业务侧的投影),企业客户是多个商户的统计口径

3.3 客户模型的微服务拆分

客户模型

从客户系统对外提供的业务主题来划分微服务:

服务主题 职责 说明
客户识别 证件识别、生物识别(人脸、指纹) 核心鉴权能力
基本信息 姓名、年龄、职业、联系方式 自然属性
管理信息 客户评级、是否内部员工、信用等级 运营属性
客户标签 多维度标记(活跃度、消费偏好、渠道来源) 分析属性
协议管理 授权协议、委托协议、隐私协议 合规属性

四、用户(User)与商户

4.1 用户

用户是客户在系统中的操作实体。用户与资金账户之间是一种授权关系——凡是被授权的用户都可以操作对应的资金账户(包括客户自己的用户,也包括被授权的其他用户)。

用户的生命周期

用户生命周期

上图展示了用户从注册(预开户/正常)到销户的完整状态流转,包括冻结等管理状态。

状态 说明
预开户 简易注册,信息不完整,需进一步完善(如设置密保问题)
正常 标准注册完成,可正常使用业务
冻结 管理状态,暂停操作权限(本应放在账户层,但互联网场景为了体验放在用户层)
销户中 销户申请后,需要先确认所有关联账户是否可销,先销账户再销用户
已销户 销户完成,释放资源(如手机号)

销户的关键流程:收到销户申请后不能直接销户——需要各业务系统确认该用户下所有账户是否可以销户(有无未结债务、有无冻结资金)。确认无问题后,先销资金账户,再销用户,最后释放占用的资源(如注册手机号)。

手机号更换:用户更换手机号时,新旧两个手机号都需要验证。如果手机号同时作为客户识别的主键,还需要更新客户 ID 的关联关系——这是互联网用户系统中最容易出 Bug 的环节之一。

4.2 商户

商户是企业客户在业务侧的投影——可以理解为资金账户分组的一种手段。一个企业可以开通多个商户,每个商户的业务资金进入各自的分类资金账户,但所有资金账户的归属关系不变,都属于企业客户这个实体。

商户和用户的关系:商户不是用户,而是和用户平级的概念。用户是"操作者",商户是"资金归集单元"。


五、账户(Account)

5.1 基本概念

账户是用于交易和结算的资金或资源凭证。理解账户建模,需要先厘清几组关键概念:

支付账户 vs 登录账户:这是两个不同业务领域的概念。支付账户是资金所有者权益的凭证(零钱、储值卡),登录账户是系统登录的凭证(手机号+密码)。一个用户可以有多个支付账户,但支付账户不会在多个登录账户之间共用。

内部账户 vs 外部账户:内部账户是系统自建的(零钱账户、储值卡账户),可以知道全部明细和余额。外部账户是用户在第三方机构的账户(银行卡、支付宝),系统只能记录本系统内的交易明细,无法得知真实余额。

收款账户 vs 收单账户:对接银行或第三方支付时,需要在渠道侧开设收款账户。在电商侧建立对应的收单账号,用来记录通过该渠道的交易流水,支持对账。

会计科目:对交易进行分类的层级结构。一级科目的汇总称为总账,详细记录称为明细。电商系统中需要为商户、买家、渠道分别建立总账和明细账户。

本文后续的账户建模(5.4 节和第九章)聚焦内部账户的设计。外部账户(银行卡、第三方支付)的建模主要是记录关联信息和本系统内的交易明细,收单账户的建模主要是支持对账,两者的详细设计不在本文展开范围内。

5.2 央行三类账户

央行对个人银行账户实施分类管理,这对支付系统的账户设计有直接影响:

央行三类账户

上图展示了央行 I/II/III 类账户的功能范围和限额差异,以下是核心对比:

类型 开立方式 功能范围 限额
I 类户 面对面核实身份 全功能(存取、转账、理财、支付) 无限额
II 类户 电子渠道,绑定 I 类户验证 5 要素 存取、转账、理财、限额支付 日累计 1 万
III 类户 电子渠道,绑定验证 4 要素 小额支付、缴费 余额上限 2000,日累计 5000

同一人在同一银行只能开一个 I 类户。II/III 类户需绑定已有银行账户验证。

5.3 账户生命周期

账户生命周期

上图展示了账户从开户到销户的完整状态流转。核心状态流转:开户→正常→(冻结↔解冻)→止付→销户。与客户生命周期的状态机设计保持一致,方便在客户层面做级联控制。

5.4 账户建模

账户建模需要满足五大业务需求,按优先级排序:

需求 说明 优先级
交易 检查账户状态(是否锁定、余额是否足够、是否有效) P0
记账 记录账户上的所有行为(支出、充值、转账) P0
对账 核对交易和余额是否正确(与渠道、商户、个人对账) P1
风控 反洗钱、反欺诈等,依赖账户数据 P2
信用 用户和商户的信用评估,依赖账户历史数据 P3

常见账户类型

类型 说明 适用场景
零钱账户 电商内部账户 用户充值、商户结算
虚拟币账户 积分、金币等虚拟资产 游戏、会员体系
代扣账户 定期自动扣款 订阅服务
银行卡账户 关联用户的银行卡 支付、提现
第三方支付账户 关联用户在支付宝/微信的账户 支付
结算账户 与银行/支付机构结算 商户结算

账户的核心属性设计

属性分类 字段 说明
基本属性 账户 ID 系统自动生成,编码规则需包含账户类型(如前 3 位表示类型)
账户名称 用户自定义,显示用
货币类型 多币种场景下,每个币种建立独立子账户
会计科目代码 关联一级会计科目
控制属性 是否允许充值/提现/支付/转账/透支 细粒度权限控制
是否激活/是否冻结 生命周期状态
资金属性 当前余额 = 可用余额 + 冻结余额
可用余额 可即时使用的金额
冻结余额 暂不可用(如支付时先冻结,出库后扣款)
第三方关联 第三方实体 ID、账号、app_id、失效日期 关联外部账户

安全提醒:用户密码、信用卡 CV 号等敏感信息不能明文存储。密码需加密保存(甚至独立存表),可增加校验字段防止数据被篡改。


六、三层身份模型

三户模型主要面向交易和资金场景。但在社交、内容、SaaS 等非交易场景中,用户身份有另一套建模逻辑——三层身份模型(Tripartite Identity Pattern)

6.1 三层结构

层级 名称 性质 可变性 可见性
第一层 账户标识符(DB Key) 系统内部唯一 ID 永久不变 用户不可见
第二层 登录标识符(Session Auth) 登录凭证 可更换 仅用户可见
第三层 公开标识符(Social Identity) 昵称、头像等公开信息 随时可改 所有人可见

第一层:账户标识符。系统自动生成的内部 ID,用于数据库关联和内部通信。它必须永久且唯一,不受用户控制,对用户不可见(或至少是惰性的)。关键原则:账户标识符不能是手机号、邮箱等可变信息——否则用户换手机号就会导致全量数据迁移。

第二层:登录标识符。创建会话时需要的凭证,通常是账号/密码对(手机号、邮箱或用户名 + 密码)。将登录标识符和账户标识符分离的核心价值是:

  • 用户更换登录方式(从手机号改为邮箱)不影响任何业务数据
  • 可以为同一个账户绑定多个登录方式(手机号 + 微信 + Apple ID)
  • 通过 OAuth 授权登录时,第三方身份作为一种登录标识符挂载到已有账户上

第三层:公开标识符。用户希望被其他用户感知的身份——昵称、头像、签名、年龄、性别等。它是一个复合对象,有时需要唯一(如微博的 @用户名),有时不需要(如微信的昵称可以重名)。

6.2 为什么要分三层

如果不分 后果
用 手机号 做数据库主键 用户换手机号 → 全量数据迁移
用 登录账号 做公开昵称 泄露登录凭证,安全风险
用 昵称 做登录账号 改昵称 → 登录失败
所有登录方式共用一个字段 无法支持多端登录和第三方授权

三层分离后:底层 ID 永远不变(数据稳定性),中间层可以灵活更换登录方式(用户体验),顶层可以随意修改公开信息(社交灵活性)。三层互不干扰。

6.3 多端登录与 OAuth 的设计

三层身份模型天然支持多种登录方式的聚合:

登录方式 实现 关联关系
手机号 + 密码 内部认证 登录标识符 → 账户标识符
微信授权登录 OAuth 2.0 微信 OpenID 作为一种登录标识符
Apple ID 登录 Sign in with Apple Apple User ID 作为一种登录标识符
邮箱 + 密码 内部认证 邮箱作为一种登录标识符

多种登录标识符指向同一个账户标识符——用户无论从哪种方式登录,看到的都是同一份数据。首次通过新方式登录时,系统需要引导用户将新的登录标识符绑定到已有账户上(或创建新账户)。


七、三户模型与三层身份模型的关系

两个模型从不同角度切入用户体系建模,互补而非替代

维度 三户模型 三层身份模型
解决的问题 交易类系统中客户、用户、账户怎么建模 认证和社交场景中身份标识怎么分层
核心关注 资金流和权限控制 身份识别和登录体验
典型场景 电商、支付、金融 社交、内容、SaaS
切分依据 按业务域切分(社会域/业务域/资金域) 按可见性和可变性切分

在实际系统中两者可以叠加使用

  • 三户模型中的"用户"对应三层身份模型中的"账户标识符"(系统内部 ID)
  • 三户模型中的"用户登录信息"对应三层身份模型中的"登录标识符"
  • 三层身份模型中的"公开标识符"在三户模型中没有直接对应——它是社交场景的特有需求

简单说:三户模型告诉你"应该有几张表",三层身份模型告诉你"用户这张表内部应该怎么分层"。


八、不同行业的适配

三户模型并非一成不变,不同行业对三户的侧重不同:

行业 客户 用户 账户 特殊需求
电信 自然人/企业 产品实例(SIM 卡、宽带) 缴费账户 一个账户为多个产品付费
银行 自然人/企业(面签建立) 网银/手机银行登录实体 I/II/III 类银行账户 央行合规要求,面签 + 分类管理
电商 买家/卖家 登录账号 零钱、银行卡、结算账户 买卖双方是不同类型的客户
SaaS 企业(租户) 企业内部成员 订阅账户、用量账户 租户隔离,成员角色管理
社交 自然人 登录实体(弱化) 虚拟资产(金币、会员) 公开标识符比账户更重要
游戏 自然人 角色/账号 虚拟货币、道具账户 一个用户多个角色,角色也是"用户"

适配的核心原则:不需要死板地套用三户,而是根据业务的核心实体来决定——谁在用系统(客户)、用系统做什么(用户)、用系统管什么资源(账户)。如果业务不涉及资金,账户可以弱化为"资源账户"(积分、额度、存储空间);如果不涉及企业客户,客户和用户可以合并。


九、核心数据模型设计

将上述概念落到数据库设计上,以下是核心表的 ER 关系:

9.1 客户-用户-账户的关系

-- 客户表(社会域)
customer (
    customer_id     BIGINT PRIMARY KEY,   -- 系统分配的客户 ID
    customer_type   ENUM('personal', 'enterprise'),
    id_card_type    VARCHAR(20),          -- 证件类型
    id_card_no      VARCHAR(50),          -- 证件号(业务主键,加密存储)
    name            VARCHAR(100),
    status          ENUM('normal', 'frozen', 'suspended'),
    created_at      TIMESTAMP
)

-- 用户表(业务域)
-- 注意:登录凭证(手机号、邮箱等)不在此表,而在 login_credential 表
user (
    user_id         BIGINT PRIMARY KEY,   -- 系统分配的用户 ID(即三层身份模型中的账户标识符)
    customer_id     BIGINT REFERENCES customer,  -- 归属客户
    user_type       ENUM('personal', 'merchant_operator'),  -- 个人用户 / 商户操作员
    status          ENUM('pre_open', 'normal', 'frozen', 'closing', 'closed'),
    created_at      TIMESTAMP
)

-- 登录凭证表(三层身份模型的第二层,支持多种登录方式)
login_credential (
    credential_id   BIGINT PRIMARY KEY,
    user_id         BIGINT REFERENCES user,      -- 归属用户
    login_type      ENUM('phone', 'email', 'wechat', 'apple', 'username'),
    login_key       VARCHAR(200),         -- 手机号/邮箱/OpenID/用户名
    login_secret    VARCHAR(200),         -- 密码 Hash(第三方登录为空)
    status          ENUM('active', 'disabled'),
    created_at      TIMESTAMP
)

-- 账户表(资金域)
account (
    account_id      BIGINT PRIMARY KEY,   -- 账户 ID(编码规则含账户类型)
    customer_id     BIGINT REFERENCES customer,  -- 归属客户
    account_type    ENUM('cash', 'virtual_coin', 'bank_card', 'settlement'),
    currency        VARCHAR(10) DEFAULT 'CNY',
    balance         DECIMAL(18,2),        -- 当前余额
    available       DECIMAL(18,2),        -- 可用余额
    frozen          DECIMAL(18,2),        -- 冻结余额
    status          ENUM('normal', 'frozen', 'suspended', 'closed'),  -- suspended = 止付
    created_at      TIMESTAMP
)

-- 商户表(企业客户在业务侧的投影)
merchant (
    merchant_id     BIGINT PRIMARY KEY,   -- 商户 ID
    customer_id     BIGINT REFERENCES customer,  -- 归属企业客户(一个企业可有多个商户)
    merchant_name   VARCHAR(200),
    business_type   VARCHAR(50),          -- 经营类型
    status          ENUM('normal', 'frozen', 'closed'),
    created_at      TIMESTAMP
)

-- 用户-账户授权关系(多对多)
user_account_auth (
    user_id         BIGINT REFERENCES user,
    account_id      BIGINT REFERENCES account,
    permission      ENUM('query', 'operate', 'admin'),  -- 授权级别
    PRIMARY KEY (user_id, account_id)
)

-- 公开资料表(社交域,三层身份模型的第三层)
user_profile (
    user_id         BIGINT PRIMARY KEY REFERENCES user,
    nickname        VARCHAR(100),
    avatar_url      VARCHAR(500),
    bio             VARCHAR(500),
    gender          ENUM('male', 'female', 'unknown'),
    updated_at      TIMESTAMP
)

9.2 关键设计要点

设计点 说明
customer_id 和 user_id 分离 客户是自然人/法人(身份证唯一),用户是登录实体(可以有多个)
user 表不存手机号 登录凭证全部在 login_credential 表,user 表只有系统 ID,避免换手机号影响用户主键
login_credential 独立成表 支持多种登录方式,更换登录方式不影响 user_id
merchant 通过 customer_id 归属 商户是企业客户的业务投影,一个企业可开通多个商户
account 通过 customer_id 归属 账户属于客户而非用户,用户通过授权关系操作账户
user_account_auth 多对多 企业客户的多人操作同一账户场景
user_profile 独立成表 公开信息和登录信息分离,改昵称不影响认证
证件号加密存储 敏感信息加密,防止拖库泄露
余额拆分为三个字段 balance = available + frozen,支付时先冻结再扣款

总结

用户体系建模的核心问题不是"怎么建 user 表",而是识别出业务中有几个本质不同的实体,以及它们之间的关系

三户模型给出了交易场景的答案:客户(你是谁)、用户(你能做什么)、账户(你有什么)——三者分属社会域、业务域、资金域,各自有独立的生命周期和状态机。

三层身份模型给出了认证和社交场景的答案:账户标识符(永久不变的内部 ID)、登录标识符(可更换的凭证)、公开标识符(可随意修改的社交身份)——三层按可变性和可见性分离,互不干扰。

两者不是二选一,而是从不同维度切入同一个问题。在实际系统中,三户模型决定了"应该有几张核心表",三层身份模型决定了"用户表内部应该怎么分层"。把两者叠加使用,就是一套完整的用户体系建模框架。

加载导航中...

评论