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

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 f

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

  }

  }

时间: 2024-10-11 11:04:18

ThinkPHP处理海量数据分表机制详细代码及说明的相关文章

重磅来袭,使用CRL实现大数据分库分表方案

关于分库分表方案详细介绍 http://blog.csdn.net/bluishglc/article/details/7696085 这里就不作详细描述了,本方案拆分结构表示为 会员为业务核心,所有业务围绕会员来进行,所以垂直划分用会员编号作索引,将会员分配到不同的库 会员订单增长量是不固定的,所以需要平水拆分,和分库一样,一个表只存指定会员编号区间的订单 了解基本需求,就可以制作方案了,以下主索引表示主数据编号 库表结构配置 进行操作时,需要知道这个数据放在哪个库,哪个表,因此需要把这个划分

Mysql5.7—mysql优化分区、分表(必备)

小生博客:http://xsboke.blog.51cto.com 小生 Q Q:1770058260 -------谢谢您的参考,如有疑问,欢迎交流 一. 分表 1. 分表简介 分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体表. 如果正在使用的表需要进行分区,就需要同时修改app的规则,使mysql可以得知用户查询的数据在哪. 2. 分表类型 分为垂直切分和水平切分 垂直切分:将某些列分到另一个表 水平切分:将某些行分到另一个表 3. 分表的方式 1) Mysql集群 它并不是

关于Mysql分区和分表

[分区概念]分区就是把一张表的数据按照一定的规则分成多个区块,这些区块可以在同一个磁盘上,也可以在不同的磁盘上.分区后表还是一张表.分区根据一定的规则把数据文件和索引文件进行了分割,还多出了一个.par文件,打开.par文件后你可以看出这张表的分区信息. [分区好处]突破磁盘的I/O瓶颈,从而达到提高mysql性能的目的.便于表的维护管理,不需要修改程序代码. [分区方法]根据分区策略创建或修改表时对表数据进行分区(分区策略多样,实现容易) [分表概念]分表是真正的分表,一张表分成很多表后,每一

Yii 读写分离 分表分库

本文转自  http://hudeyong926.iteye.com/blog/1299989 实现一主一从,一主多从,多主多从的读写分离 .支持DAO,AR,其中Query builder只完成部分,需完善 调用 Java代码   //AR class User extends ActiveRecord { public $useDbName= 'passport'; //$this->dbWrite(); } //$connection = $model->getDbConnection(

一次分表踩坑实践的探讨

前言 之前不少人问我“能否分享一些分库分表相关的实践”,其实不是我不分享,而是真的经验不多??:和大部分人一样都是停留在理论阶段. 不过这次多少有些可以说道了. 先谈谈背景,我们生产数据库随着业务发展量也逐渐起来:好几张单表已经突破亿级数据,并且保持每天 200+W 的数据量增加. 而我们有些业务需要进行关联查询.或者是报表统计:在这样的背景下大表的问题更加突出(比如一个查询功能需要跑好几分钟). 可能很多人会说:为啥单表都过亿了才想方案解决?其实不是不想,而是由于历史原因加上错误预估了数据增长

如何设计可以动态扩容缩容的分库分表方案?

对于分库分表来说,主要是面对以下问题: 选择一个数据库中间件,调研.学习.测试: 设计你的分库分表的一个方案,你要分成多少个库,每个库分成多少个表,比如 3 个库,每个库 4 个表: 基于选择好的数据库中间件,以及在测试环境建立好的分库分表的环境,然后测试一下能否正常进行分库分表的读写: 完成单库单表到分库分表的迁移,双写方案: 线上系统开始基于分库分表对外提供服务: 扩容了,扩容成 6 个库,每个库需要 12 个表,你怎么来增加更多库和表呢? 是你必须面对的一个事儿,就是你已经弄好分库分表方案

分库分布的几件小事(三)可以动态扩容缩容的分库分表方案

1.扩容与缩容 这个是你必须面对的一个事儿,就是你已经弄好分库分表方案了,然后一堆库和表都建好了,基于分库分表中间件的代码开发啥的都好了,测试都ok了,数据能均匀分布到各个库和各个表里去,而且接着你还通过双写的方案咔嚓一下上了系统,已经直接基于分库分表方案在搞了. 那么现在问题来了,你现在这些库和表又支撑不住了,要继续扩容咋办?这个可能就是说你的每个库的容量又快满了,或者是你的表数据量又太大了,也可能是你每个库的写并发太高了,你得继续扩容. 缩容就是现在业务不景气了,数据量减少,并发量下降,那么

分库分布的几件小事(二)如何进行分库分表的数据迁移

1.停机迁移方案 这是最简单的也是最low的迁移方案了,如果系统就算短期停机也没有关系或者造不成多大的影响,可以选用此方案. 首先停掉机器,将系统全都停掉,不要再有新的数据进来,然后使用之前写好的程序,连接旧的数据库,将旧数据库里面的数据读出来,然后通过数据分发中间件写到分库分好的数据里面去.然后修改系统是数据库连接.分库分表配置,然后重新上线. 2.双写不停机迁移方案 双写迁移方案的核心在双写,首先要修改系统所有需要写库的地方,将虽有对数据的写操作不但要写入就库,也要同时写入新库. 然后使用写

系统从未分库分表动态切换到分库分表

停机迁移方案 我先给你说一个最 low 的方案,就是很简单,大家伙儿凌晨 12 点开始运维,网站或者 app 挂个公告,说 0 点到早上 6 点进行运维,无法访问. 接着到 0 点停机,系统停掉,没有流量写入了,此时老的单库单表数据库静止了.然后你之前得写好一个导数的一次性工具,此时直接跑起来,然后将单库单表的数据哗哗哗读出来,写到分库分表里面去. 导数完了之后,就 ok 了,修改系统的数据库连接配置啥的,包括可能代码和 SQL 也许有修改,那你就用最新的代码,然后直接启动连到新的分库分表上去.