时间:2021-07-01 10:21:17 帮助过:5人阅读
应用ThinkPHP内置的分表算法处理百万级用户数据. 数据表: house_member_0 house_member_1 house_member_2 house_member_3 模型中 class MemberModel extends AdvModel { protected $partition = array('field'=>'username','type'=>'id','num'=>'4'); public function getDao($data=array()) { $data = empty($data) ? $_POST : $data; $table = $this->getPartitionTableName($data); return $this->table($table); } } 方法中 class MemberAction extends BaseAction { public function login() { if($this->isPost()) { $this->validToken(); $dao = D('Member')->getDao(); $res = $dao->where('username = '.$_POST['username'])->find(); // output 为自定义方法 // $isAjax - bool $this->output(false); } $this->display(); } } /** +---------------------- * 得到分表的的数据表名 +---------------------- * @access public +---------------------- * @param array $data 操作的数据 +---------------------- * @return string +---------------------- */ public function getPartitionTableName($data=array()) { // 对数据表进行分区 if(isset($data[$this->partition['field']])) { $field = $data[$this->partition['field']]; switch($this->partition['type']) { case 'id': // 按照id范围分表 $step = $this->partition['expr']; $seq = floor($field / $step)+1; break; case 'year': // 按照年份分表 if(!is_numeric($field)) { $field = strtotime($field); } $seq = date('Y',$field)-$this->partition['expr']+1; break; case 'mod': // 按照id的模数分表 $seq = ($field % $this->partition['num'])+1; break; case 'md5': // 按照md5的序列分表 $seq = (ord(substr(md5($field),0,1)) % $this->partition['num'])+1; break; default : if(function_exists($this->partition['type'])) { // 支持指定函数哈希 $fun = $this->partition['type']; $seq = (ord(substr($fun($field),0,1)) % $this->partition['num'])+1; }else{ // 按照字段的首字母的值分表 $seq = (ord($field{0}) % $this->partition['num'])+1; } } return $this->getTableName().'_'.$seq; }else{ // 当设置的分表字段不在查询条件或者数据中 // 进行联合查询,必须设定 partition['num'] $tableName = array(); for($i=0;$i<$this->partition['num'];$i++) $tableName[] = 'SELECT * FROM '.$this->getTableName().'_'.$i; $tableName = '( '.implode(" UNION ",$tableName).') AS '.$this->name; return $tableName; } }
?