多渠道账号的表设计想法

分类: 工作

对于app来说很多时候需要很多种登录渠道,例如 手机号登录、邮箱登录、微信登录等等,并且可能在后期还会增加增加。数据库如何设计是我最近在思考的。

现有方案以及的问题

我们现在的表设计如下:

create table account(
    id int auto_increment primary key,
    uid varchar(30) not null unique comment '用户唯一id',
    mobile varchar(15) unique not null comment '手机号码',
    password varchar(30) not null comment '密码',
    wx_openid varchar(30) unique comment '微信openId',
    wx_uninoid  varchar(30) unique comment '微信uninoid'
)

其中存在一些问题:

  1. 首先我们将手机号作为了用户的唯一标识。这是我们默认所有用户都有手机号。对于某些场景时例如使用微信openid登录时,此时的设计是必须是需要用户填写手机号的,否则无法成功插入数据,完成注册。虽然可以在这个字段填写随机字符串达到效果,但是非常不优雅。

  2. 无法很好的拓展第三方登录渠道。在上面的表设计中有一个很奇怪的点,就是一行中同时出现了 wx 的 openid 和 uininoid 两个字段。那加入我们的程序要引入支付宝登录,google登录怎么办,继续加 xx_openid 字段吗?

新方案

将原 account 设计分成两个表 accountaccount_auth

account

create table account(
    id int auto_increment primary key,
    uid varchar(30) not null unique comment '用户唯一id'
)

account_auth

create table account_auth (
    id int auto_increment primary key,
    uid varchar(30) not null comment '绑定的uid',
    type varchar(30) not null comment '认证类型',
    value varchar(50) not null comment '认证值'    
)

对于 account_auth 的使用

Id uid type value
1 user1 wx_openid Xxxxxxxxxxxxxxxxxxx
2 user1 mobile 13000000000
3 user2 qq_openid Xxxxxxxxxxxxxxx

在验证时,可以使用如下 sql 进行校验。

select uid from account right join account_auth aa on uid = aa.uid where uid = ? and type = ? and value = ?

将登录渠道等信息与账号信息分离,可以十分方便新增第三方渠道,主表也不需要因为新增了一个渠道而频繁改变结构,增加各种约束索引。对于账号信息,也方便了对于游客模式的处理,无需对需要的唯一必填项进行特殊处理。


上一篇: Github + OSS + CDN 搭建静态博客
下一篇: Go的函数式选项模式