ThinkPHP处理海量数据分表机制详细代码及说明

应用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);

}

}

方法中 phperz.com

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 www.phperz.com

+----------------------------------------------------------

* @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;

}

} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值