文档更新说明
- 2016-03-26 完成
- 2016-03-25 初稿
前言
在可绑定可扩展的帐号系统设计原理及其实现(一)一文中已经啰嗦讲完原理了.本文主要借用PHP代码从实现角度讲述.分成用户注册,帐号绑定,数据迁移,数据查询四个部分.
用户注册
手机号注册
手机号注册的帐号,称为主帐号,实现起来相对比较简单,只需要在users表中插入一条主帐号数据即可.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
|
public function addOne($data) { if ( isset($data['phone']) && isset($data['nickname']) ) { $data['created_at'] = $data['updated_at'] = date('Y-m-d H:i:s',time()); $this->db->query("BEGIN"); try{ if($this->db->insert($this->_tablename,$data)){ $last_id = $this->db->Insert_ID(); $where_string = 'id = '.$last_id; $this->db->update($this->_tablename,array('nickname'=>$last_id),$where_string,1); $accModel = new AccountModel(); $accResult = $accModel->addOne($last_id); if (!$accResult) { throw new Exception("Can not insert to accounts"); } }else{ throw new Exception("Can not insert to users"); }
$this->db->query("COMMIT"); return $last_id; } catch (Exception $e) { $this->db->query("ROLLBACK"); log_result("Roll back : ".$e->getMessage); return false; } } return false; }
|
第三方帐号注册
第三方帐号注册相对手机号注册要复杂一点点.先在open_users中插入第三方帐号信息,接着在users表中插入一条占位数据,最后在user_aliases中插入一条自关联数据,这样查询数据就可以不区分登录的帐号是主帐号还是第三方帐号.由于users表中的phone是唯一非空字段,所以占位数据的phone自动采用虚拟的方式phone=v+第三方表记录id.
注册第三方帐号时在users表中的占位数据在绑定手机号时,如果手机号从未注册,那这条记录也会变成主帐号,如果手机号已经注册过了,这条记录才是真正作废.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
|
public function addOne($data) { $ouid = 0; $user_id = 0; if (isset($data['nickname']) && isset($data['openid']) && isset($data['genre'])){ $data['created_at'] = $data['updated_at'] = date('Y-m-d H:i:s',time()); $openuserData = []; $openuserData['openid'] = $data['openid']; $openuserData['genre'] = $data['genre']; $openuserData['created_at'] = $openuserData['updated_at'] = $data['created_at']; $this->db->query("BEGIN"); try { if($this->db->insert($this->_tablename,$openuserData)){ $ouid = $this->db->Insert_ID(); $vphone = "v{$ouid}"; $userData = []; $userData['avatar'] = $data['avatar']; $userData['nickname'] = $data['nickname']; $userData['phone'] = $vphone; $userData['created_at'] = $userData['updated_at'] = $data['updated_at']; if(!$this->db->insert('users',$userData)){ throw new Exception("Can not insert to users"); } $user_id = $this->db->Insert_ID(); $accModel = new AccountModel(); if (!$accModel->addOne($user_id)) { throw new Exception("Can not insert to accounts"); }
$where_string = 'id = '.$ouid; if(!$this->db->update($this->_tablename,array('user_id'=>$user_id),$where_string,1)){ throw new Exception("Can not update open_users"); }
$aliasesData = []; $aliasesData['alias_user_id'] = $aliasesData['user_id'] = $user_id; if(!$this->db->insert('user_aliases',$aliasesData)){ throw new Exception("Can not insert to alias_user_id"); } }else{ throw new Exception("Can not insert to open_users"); } $this->db->query("COMMIT"); return $user_id; } catch (Exception $e) { $this->db->query("ROLLBACK"); log_result("Roll back : ".$e->getMessage); exit; } } return false; }
|
帐号绑定
用户登录第三方帐号后,操作绑定手机号码时,先检查用户给出的phone是否存在users表的phone字段.手机号码可能已经存在主帐号中也可能是一个全新的号码,所以帐号绑定分成两种情况,下面分别说明.
手机号未注册
手机号码从未注册过,说明手机号码不存在users表中.所以第三方帐号在users表中的占位数据可以直接更新为主帐号->直接将users表中phone字段更新为绑定的手机号即可.
手机号已注册
对于手机号已经注册过的,先找到手机号所在行id(也就是主id),把主id更新到open_users表的user_id字段,然后在user_aliases表中追加一条记录:
1 2 3 4
| $aliasesData = []; $aliasesData['user_id'] = 主id; $aliasesData['alias_user_id'] = 占位id; $this->db->insert('user_aliases',$aliasesData);
|
数据迁移
由于表结构已经做了设计优化,数据迁移时,只需要在accounts表中,把第三方帐号中的数据转入主帐号中就可.至于其他消费记录购买记录等等一概不需要做任何改动~😋
数据查询
最后一部分就是数据查询了.根据数据库的设计,我们只需要得到任何一个第三方uid或者主帐号uid,即可从user_aliases表中反查出所有的关联id,然后只需要在任何需要查询记录的表中使用SQL的in语法即可查询到数据.
1 2 3
| $sql = "select feature from `orders` where `orders`.user_id in (id1, id2, id3, ...)"; $some_data = $this->db->executeS($sql);
|