用户中台的用户模型应该怎样设计

先从场景开始

场景:你们公司有两个业务线,对外有两个App,分别是 A 和 B,小明在两个App上都注册了,他的用户数据应该怎样存储?

如果两个业务线有各自的用户系统
业务会各自存储自己的用户数据,就是App A有张用户表,App B有张用户表,两个App的数据是完全独立的。

如果是用户中台统一存储用户数据的话,一般也是两条数据,可能是存在一张表里,通过app区分,例如

app, 手机号, 昵称, 密码
A, xx, xx, xx
B, xx, xx, xx

如果是也可能是按照业务分表的做法,app A 的数据存在user_a,app B的数据存在user_b中。

这些方案都是很容易就想到的。

我们公司的业务线是没有独立的用户系统的,都是依托用户中台的,假设是你,
现在你们老板提了个需求,需要把这多个业务线的用户数据打通(不需要用户参与,用户注册时数据自动关联)。可能你脑子里已经有方案了,但接下来我要和你介绍我们的方案,这也是我司用户中台迭代的三个版本。

第一个版本

关键词:依托答辩

数据库使用的是mongo,上面例子的数据是这么存的

{
    "id": "xxx",
    "name": "xx",
    "phone": "xxx",
    "app": [
        "a",
        "b"
    ],
    "password": "xxx"
}

通过手机号码关联不同业务之间的数据,app表示用户注册过的app。
从这条数据不难联想到以下几个问题:
1。如果用户在App a 上把手机号换了,其他已经注册的app岂不是也换了,用原本的账号登录不了了?!

是的,这也是导致很多用户反馈过的问题。后来我们把换号的逻辑改了,换号时,如果app不仅仅包含当前的app,那就不修改原数据,改为根据新号码创建或修改数据

2。密码都用了一个,也会出现一个app换密码,其他app密码都换了的情况,怎么办呢?

增加了app独立的密码字段app_a_password,登录时,如果有这个字段,会用这个密码校验

3。用户注销怎么办

直接从app列表里,把注销的app删掉

4。如果App A的用户和App B的用户属性不一致怎么办

效仿密码的处理,于是用户数据里多了一些这样的字段app_a_nickname,app_a_delete_time,app_b_status

于是用户数据就成了

{
    "_class": "java.util.HashMap",
    "_id": "xxx",
    "phone": "xx",
    "account": "xx",
    "app_b_id": "xx",
    "alias_id": [
        "vBglqAqd6Sf",
        "349954228"
    ],
    "app_a_pdate":NumberLong(1573818941),
    "app_a_shop_code": "03064794",
    "app_a_status":NumberInt(1),
    "app_a_title": "李s卫",
    "app_a_type": "1",
    "app_a_type2": "7",
    "app_a_id": "vBglqAsxq6Sf",
    "date_create":ISODate("2019-11-15T11:55:41.000Z"),
    "id": "vBglqAq6Sf",
    "iid":NumberInt(349954228),
    "personal_shop_code": "03093255",
    "regip": "180.152.24.41",
    "app_a_avatar": "",
    "weixin": "13262709697",
    "identity": NumberInt(0),
    "app": [
        "a",
        "b"
    ]
}

除了数据库存储的事一坨之外,对外接口,代码逻辑也是一坨。。。

大佬总结

用户信息、员工信息、账号信息、状态、店铺code、个人钱包code 全部都糅杂在一条数据上。 这就算了,主要是多个不同业务域的
用户信息、员工信息、账号信息、状态、店铺code、个人钱包code 也全部都糅杂在一条数据上。

简单四个字:

罄竹难书

测试看了会流泪,用户看了会沉默:
1 因为原用户系统奇葩的调用拓扑
2 因为原用户系统诡异的代码实现
3 因为原用户系统面目全非的范接口的存在
4 因为原用户系统秉承着最底层业务所以无业务逻辑,但是却在Dao层写满了互相干扰的业务逻辑的神操作

后人互勉

要想练就绝世武功,就要忍受常人难忍受的痛

第二个版本

第一个已经是依托答辩了,第二个版本也是在第一托上稍微优化了下

底层数据库不适用mongo了,通过数据迁移、双写等方案,逐步将mongo上的数据迁移到了mysql中,并且按业务做了数据分离。
上面的例子,数据分别存在了 user_app_a 和 user_app_b 中。
如何解决老板的需求,把多个业务的用户数据打通呢?引入了一个uid和一张用户基础表 user_base。
user_base中存储了用户基本信息,并为每个用户生成了一个唯一的uid。
业务用户表user_app_a写入时,会查询用户基础表,得到uid,user_app_a表中的用户数据会通过uid关联到user_base。

这么设计好像没啥问题哈,但是有些业务表没有存用户手机号码,而是用用户基础表中的手机号,所以还是存在上面那个换手机号码的问题。

接口和代码逻辑里,用户对象全都是map。。。

大佬忍不住了

现实模型:
1、一个人,常规情况下,99.9999999% 他是有只一个身份证号码的。
2、一个人,常规情况下,他可以凭着自己的意愿去营业厅买电话号码的。
或一张电信sim卡,或两张sim联通卡,或三张电信sim卡(实名认证之后一个人最多拥有5张卡)。
3、一个人,常规情况下,他可以凭着自己的意愿去营业厅注销他自己的sim卡的。
或一张,或两张,或全部(只要他没欠费,没有涉嫌刑事备注)。
4、一个人,常规情况下,他是可以在自己的APP里面换电话号码的,或一年一次、或半年一次、或每天都可以、或只要手速够快每秒钟都可以。

所以一个常规的正常的用户系统 为什么 换电话号码会是个问题呢?

所以为什么我们要去讨论这个问题呢?

第三个版本

在这个版本,我们终于可以正常的更换手机号码了!!!

在第二个版本的基础上,不再通过uid和用户基础表强关联了。

不再使用map了。不同的业务允许有不同的用户模型,有不同的接口,不同的逻辑。
真的是天下大势,分久必合,合久必分。。。

用户模型应该怎么设计呢

这个问题我还没有很好的答案
一个物理人在一个应用域下可以有多个用户(未实名认证)。

一个用户在一家企业(店铺/集团)下有一个员工,但是一个用户可以在多家企业(店铺/集团)下都有任职,从而一个用户是可以有多个不同企业的员工身份。

一个员工为了使用 其它服务能力,必须拥有账号做为操作的载体,从而一个员工在所属的店铺/集团下可以有多个账号,实现不同的职能划分。

用户和员工、账号的性质区分
用户:属于个人
员工、账号:属于企业组织
在组织的层面上,强烈要求只允许修改 员工,账号的信息,用户信息的操作不以组织的意志为转移,组织对用户只能有读的能力。
在属性设计时要明确哪些是企业的信息和要用到的信息,要维护到员工、账号中去,哪些是个人信息,可以维护到用户中。从模型概念上说,用户只属于个人,所以他可以任职且被多个组织可见,如果其中一个组织修改了用户的信息,会影响到其他的组织对用户的使用。

用户的唯一性
用户中有唯一判别其他用户的业务属性,如手机号、邮箱等等。没有唯一性的用户会不可控,破坏业务的发展。

账号的使用必须依赖于存在的用户
一个可执行的账号,是依赖员工、店铺存在的,而员工是依赖用户存在的。
必须要有所属用户,账号才可以进行业务操作

  • 20
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lanicc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值