mysql表的设计⼏种⽅式_⽀持多种登录⽅式的数据表设计六阿
动森
哥博客
⼀个带有⽤户系统的应⽤最基本登录⽅式是站内账号登录,但这种⽅式往往不能满⾜我们的需求。现在的应⽤基本都有站内账号、email、⼿机和⼀堆第三⽅登录,那么如果需要⽀持这么多种登录⽅式,或者还有银⾏卡登录、⾝份证登录等等更多的登录⽅式,我们的数据表应该怎么设计才更合理呢?
需求分析
实现多种登录⽅式,并且除了站内账号登录⽅式以外的登录⽅式,都能够进⾏绑定和解绑或者更换绑定。
如果按照传统的数据表设计,我们⽤户表会存储⽤户的账号和密码等授权相关的字段,类似下⾯:
id
username
password
nickname
sex
...
1
2
3
4
5
6
id
username
password
nickname
sex
...
但是如果登录⽅式⾮常多的情况下,这种数据表结构不再适⽤。那么应该怎么设计呢?在查阅了⼀些资料后,本渣渣终于有了⼀个⾃我感觉很合理的设计⽅式。
⾸先,⼀个⽤户不管有多少种登录⽅式,⽤户还是只有那⼀个⽤户,但登录⽅式却有多种。这就形成了⼀对多的关系:⼀个⽤户对应多个登录⽅式。
所以,我们就可以把⽤户表拆分成2张表,⼀张表存储⽤户基本的数据,另⼀张表存储登录授权相关的数据。我们可以向下⾯这样设计:
users
id
nickname
sex
age
email
mobile
status
...
1
2
3
4
5
6
7
8
id
nickname
sex
age
email
mobile
status
.
..
user_auths
id # ⾃增id
user_id # users表对应的id
identity_type # ⾝份类型(站内username 邮箱email ⼿机mobile 或者第三⽅的qq weibo weixin等等) identifier # ⾝份唯⼀标识(存储唯⼀标识,⽐如账号、邮箱、⼿机号、第三⽅获取的唯⼀标识等) credential # 授权凭证(⽐如密码 第三⽅登录的token等)
verified # 是否已经验证(存储 1、0 来区分是否已经验证通过)
1
2
3
4
5
6
id#⾃增id
user_id#users表对应的id
identity_type#⾝份类型(站内username邮箱email⼿机mobile或者第三⽅的qqweiboweixin等等)
identifier#⾝份唯⼀标识(存储唯⼀标识,⽐如账号、邮箱、⼿机号、第三⽅获取的唯⼀标识等)
credential#授权凭证(⽐如密码第三⽅登录的token等)
verified#是否已经验证(存储1、0来区分是否已经验证通过)
这样我们创建⼀个⽤户,⾸先需要创建⼀条 users 表的⽤户基础信息记录和⼀条或者多条 user_auths 表的授权记录。注意修改密码时也需要同时修改多条 user_auths 记录,保证需要密码的登录⽅式凭证需要同步更新。⽽第三⽅的授权凭证和需要密码的授权凭证则不需要同步。
代码实现
这⾥我使⽤ laravel 来实现简单的⽤户注册、登录、修改密码等操作,仅供参考。
⾸先创建2张数据表,结构如下:
users
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('nickname', 30)->default('宝宝')->comment('昵称');
$table->string('say')->nullable()->comment('⼼情寄语');
$table->string('avatar', 50)->default('uploads/user/avatar.jpg')->comment('头像');
$table->string('mobile', 11)->nullable()->comment('⼿机号码');
$table->string('email', 50)->nullable()->comment('邮箱');
$table->tinyInteger('sex')->default(0)->comment('性别 0⼥ 1男');
$table->tinyInteger('status')->default(1)->comment('状态 1可⽤ 0 不可⽤');
$table->tinyInteger('is_admin')->default(0)->comment('是否是管理员');
$table->tinyInteger('qq_binding')->default(0)->comment('QQ登录是否绑定');
$table->tinyInteger('weixin_binding')->default(0)->comment('登录是否绑定');
$table->tinyInteger('weibo_binding')->default(0)->comment('微博登录是否绑定');
$table->tinyInteger('email_binding')->default(0)->comment('邮箱登录是否绑定');
$table->tinyInteger('phone_binding')->default(0)->comment('⼿机登录是否绑定');
$table->timestamps();
});
}
每加仑等于多少升1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
publicfunctionup()
{
Schema::create('users',function(Blueprint$table){
$table->increments('id');
$table->string('nickname',30)->default('宝宝')->comment('昵称');
$table->string('say')->nullable()->comment('⼼情寄语');
$table->string('avatar',50)->default('uploads/user/avatar.jpg')->comment('头像'); $table->string('mobile',11)->nullable()->comment('⼿机号码');
$table->string('email',50)->nullable()->comment('邮箱');
$table->tinyInteger('sex')->default(0)->comment('性别 0⼥ 1男');
$table->tinyInteger('status')->default(1)->comment('状态 1可⽤ 0 不可⽤'); $table->tinyInteger('is_admin')->default(0)->comment('是否是管理员');
$table->tinyInteger('qq_binding')->default(0)->comment('QQ登录是否绑定'); $table->tinyInteger('weix
in_binding')->default(0)->comment('登录是否绑定'); $table->tinyInteger('weibo_binding')->default(0)->comment('微博登录是否绑定'); $table->tinyInteger('email_binding')->default(0)->comment('邮箱登录是否绑定');
$table->tinyInteger('phone_binding')->default(0)->comment('⼿机登录是否绑定');
$table->timestamps();
});
}
user_auths
public function up()
{
Schema::create('user_auths', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->index()->comment('⽤户id');
$table->string('identity_type')->comment('登录类型(⼿机号phone 邮箱email ⽤户名username)或第三⽅应⽤名称(weixin 微博weibo 腾讯QQqq等)');
$table->string('identifier')->unique()->index()->comment('标识(⼿机号 邮箱 ⽤户名或第三⽅应⽤的唯⼀标识)');
蒋伟文佩甄$table->string('credential')->nullable()->comment('密码凭证(站内的保存密码,站外的不保存或保存token)');
$table->tinyInteger('verified')->default(0)->comment('是否已经验证');
一般纳税人税率$table->timestamps();2022放假安排
});
}
1轮胎寿命
2
3
4
5
6
7
8
9
10
11
12
publicfunctionup()
{
Schema::create('user_auths',function(Blueprint$table){
$table->increments('id');