|
- 应用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;
- }
- }
复制代码 |
|