天天看點

php實作MySQL讀寫分離

MySQL讀寫分離有好幾種方式 MySQL中間件 MySQL驅動層 代碼控制

關于 中間件 和 驅動層的方式這裡不做深究  暫且簡單介紹下 如何通過PHP代碼來控制MySQL讀寫分離

我們都知道 “讀” 在SQL語句裡是 “SELECT”,  ”寫” 是 “INSERT”

那麼我們第一時間就應該想到 字元串截取 substr() 這個函數

首先我們通過substr()函數來擷取到 sql語句的前6個字元是否為 “SELECT” 如果是我們連接配接讀伺服器進行處理 如果不是 我們連接配接寫伺服器進行處理

思路有了 那麼就是代碼了

$querystr = strtolower(trim(substr($sql,0,6)));    //截取SQL語句字元串

//如果是select,就連接配接slave(從)伺服器

if($querystr == 'select')

{

$slave_server='192.168.80.3::3306';

$dsn="mysql:host=$slave_server;dbname=3d";

$user='root';

$pass='root';

$dbh=new PDO($dsn, $user, $pass);

$res=$dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);

}

//如果不是select,就連接配接master(主)伺服器

else

{

$master_server='192.168.33.22::3306';

$dsn="mysql:host=$master_server;dbname=3dprintsys";

$user='root';

$pass='123456';

$dbh=new PDO($dsn, $user, $pass);

$res=$dbh->exec($sql);

}

上面的代碼流程已經很清晰了 下面把代碼整理為面向對象風格

<?php
class Db
{
  private $res;
  function __construct($sql)
  {
    $querystr = strtolower(trim(substr($sql,0,6)));  //截取SQL語句字元串
    //如果是select,就連接配接slave(從)伺服器
    if($querystr == 'select')
    {
      $res=$this->slave ($sql);
      $this->res=$res;
    }
    //如果不是select,就連接配接master(主)伺服器
    else
    {
      $res=$this->master ($sql);
      $this->res=$res;
    }
  }
 
  /**
   * slave從庫傳回sql查詢結果
   * @param $sql
   * @return array
   */
  private function slave ($sql){
//由于現實中讀伺服器的數量可能在一個以上 會引出負載均衡問題 這裡就不做闡述了 從伺服器IP我就随機擷取了
    $slave_ip=$this->get_slave_ip();
    $dsn="mysql:host=$slave_ip;dbname=test";
    $user='root';
    $pass='root123';
    $dbh=new PDO($dsn, $user, $pass);
    return $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
  }
 
  /**master主庫傳回sql執行結果
   * @param $sql
   * @return int
   */
  private function master ($sql){
    $master_ip='192.168.80.3';
    $dsn="mysql:host=$master_ip;dbname=test";
    $user='root';
    $pass='root123';
    $dbh=new PDO($dsn, $user, $pass);
    return $dbh->exec($sql);
  }
 
  /**
   * 随機擷取slave-ip
   * @return mixed
   */
  private function get_slave_ip(){
    $slave_ips=['192.168.0.1','192.168.0.2'];
    $count=count($slave_ips)-1;
    $index =mt_rand(0,$count);
    return $slave_ips[$index];
  }
 
  /**       
   * 擷取結果
   * @return int
   */
  public function get_res(){
    return $this->res;
  }
}
 
$sql1 = "select * from ecs_goods_info ";
$sql2 = "insert into ecs_goods_info (goods_name) values ('haha')";
$sql3 = "delete from ecs_goods_info where id=199";
$sql4 = "update ecs_goods_info set goods_name='金剛葫蘆娃' where id=198";
 
$db = new Db($sql1);
//$db = new Db($sql2);
//$db = new Db($sql3);
//$db = new Db($sql4);
 
var_dump($db->get_res());      
因為讀寫分離是建立在主從複制的基礎上 是以下次為大家分享下主從複制的原理