服务报价 | 域名主机 | 网络营销 | 软件工具| [加入收藏]
 热线电话: #
当前位置: 主页 > 开发教程 > mysql教程 >

mysql分库分表实战及php代码操作完整实例(2)

时间:2016-09-15 23:04来源:未知 作者:最模板 点击:
4、mysql模型类操作数据库 Model.php ?php require_once Config.php;//引入配置信息 class Model{ public $config; //数据库配置 public $connection; //pdo protected $dbnamePrefix; //库前缀
 
4、mysql模型类操作数据库
Model.php
 
<?php  
require_once 'Config.php';//引入配置信息  
class Model{    
    public $config;     //数据库配置  
    public $connection; //pdo  
    protected $dbnamePrefix; //库前缀如cloude_50 前缀为cloude   
    protected $tablePrefix;  //表前缀  
    protected $dbname;  //分库分表后对应的库  
    protected $table;   //分库分表后对应的库表  
      
    public function __construct($id){    
        $this->config = new Config($this->dbnamePrefix, $this->tablePrefix, $id);                  //根据id找到对应库和表  
        $this->connection = new Pdo($this->config->dsn, $this->config->user, $this->config->password);//实例化pdo    
        $this->connection->exec("set names utf8");     
        $this->dbname = $this->config->dbname;  
        $this->table = $this->config->table;    
    }    
      
    public function update(array $data, array $where = array()){    
      
    }    
      
    public function select(array $condition){   
        $sqlwhere='';  
        if(!empty($condition)){     
            foreach ($condition as $field => $value) {    
                $where[] = '`'.$field.'`='."'".addslashes($value)."'";    
            }    
            $sqlwhere .= ' '.implode(' and ', $where);     
        }  
        $sql="select * from ".$this->dbname.'.'.$this->table;  
        if($sqlwhere){  
            $sql.=" where $sqlwhere";  
        }  
        $res=$this->connection->query($sql);  
        $data['data']=$res->fetchAll(PDO::FETCH_ASSOC);  
        $data['info']=array("dsn"=>$this->config->dsn,"dbname"=>$this->dbname,"table"=>$this->table,"sql"=>$sql);  
        return $data;     
    }    
    public function insert(array $arrData) {  
        $name = $values = '';  
        $flag = $flagV = 1;  
        $true = is_array( current($arrData) );//判断是否一次插入多条数据  
        if($true) {  
            //构建插入多条数据的sql语句  
            foreach($arrData as $arr) {  
                $values .= $flag ? '(' : ',(';  
                foreach($arr as $key => $value) {  
                    if($flagV) {  
                        if($flag) $name .= "$key";  
                        $values .= "'$value'";  
                        $flagV = 0;  
                    } else {  
                        if($flag) $name .= ",$key";  
                        $values .= ",'$value'";  
                    }  
                }  
                $values .= ') ';  
                $flag = 0;  
                $flagV = 1;  
            }  
        } else {  
            //构建插入单条数据的sql语句  
            foreach($arrData as $key => $value) {  
                if($flagV) {  
                    $name = "$key";  
                    $values = "('$value'";  
                    $flagV = 0;  
                } else {  
                    $name .= ",$key";  
                    $values .= ",'$value'";  
                }  
            }  
            $values .= ") ";  
        }  
           
        $sql = "insert into ".$this->dbname.'.'.$this->table." ($name) values $values";  
        if( ($rs = $this->connection->exec($sql) ) > 0 ) {  
            return array("dsn"=>$this->config->dsn,"dbname"=>$this->dbname,"table"=>$this->table,"sql"=>$sql);  
        }  
        return false;  
    }  
    public function query($sql){    
        return $this->connection->query($sql);    
    }    
}  
 
5、测试
使用主键id作为分表字段,那最好就不要使用自增了,可使用uuid
User.php
 
<?php  
require 'Config.php';    
require 'Model.php';    
class User extends Model    
{    
    protected $dbnamePrefix = 'cloude';    
    protected $tablePrefix = 'user';    
}   
//生成唯一uuid  
function create_uuid($prefix = ""){    //可以指定前缀  
    $str = md5(uniqid(mt_rand(), true));     
    $uuid  = substr($str,0,8) . '-';     
    $uuid .= substr($str,8,4) . '-';     
    $uuid .= substr($str,12,4) . '-';     
    $uuid .= substr($str,16,4) . '-';     
    $uuid .= substr($str,20,12);     
    return $prefix . $uuid;  
}  
  
$userId=create_uuid();  
$user = new User($userId);  
$data=array('id'=>$userId,'name'=>'大明'.$userId,'password'=>'14e1b600b1fd579f47433b88e8d85291','sex'=>'男');    
if($result=$user->insert($data)){  
    echo '插入成功:','<pre/>';  
    print_r($result);  
}  
  
$condition=array("id"=>$userId);  
$list=$user->select($condition);  
if($list){  
    echo '查询成功:','<pre/>';  
    print_r($list);  
}  
 
6、结果
插入成功会返回插入到哪个库哪个表,查询成功返回从哪个库哪个表查的
 
mysql分库分表实战及php代码操作完整实例
 
分库分表注意事项:
1、维度问题
假如用户购买了商品,需 要将交易记录保存取来,如果按照用户的纬度分表,则每个用户的交易记录都保存在同一表中,所以很快很方便的查找到某用户的购买情况,但是某商品被购买的情 况则很有可能分布在多张表中,查找起来比较麻烦。反之,按照商品维度分表,可以很方便的查找到此商品的购买情况,但要查找到买人的交易记录比较麻烦。
所以常见的解决方式有:
通过扫表的方式解决,此方法基本不可能,效率太低了。
记录两份数据,一份按照用户纬度分表,一份按照商品维度分表。
通过搜索引擎解决,但如果实时性要求很高,又得关系到实时搜索
2、避免分表join操作 因为关联的表有可能不在同一数据库中
3、避免跨库事务
避免在一个事务中修改db0中的表的时候同时修改db1中的表,一个是操作起来更复杂,效率也会有一定影响
4、分表宜多不宜少;这样做主要是为了尽量避免后期可能遇到的二次拆分
5、尽量把同一组数据放到同一DB服务器上
例如将卖家a的商品和交易信息都放到db0中,当db1挂了的时候,卖家a相关的东西可以正常使用。也就是说避免数据库中的数据依赖另一数据库中的数据
(责任编辑:最模板)
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
栏目列表
热点内容