MySQL讀寫分離有好幾種方式 MySQL中間件 MySQL驅動層 代碼控制
關於 中間件 和 驅動層的方式這里不做深究 暫且簡單介紹下 如何通過PHP代碼來控制MySQL讀寫分離
我們都知道 “讀” 在SQL語句里是 “SELECT”, ”寫” 是 “INSERT”
那么我們第一時間就應該想到 字符串截取 substr() 這個函數
首先我們通過substr()函數來獲取到 sql語句的前6個字符是否為 “SELECT” 如果是我們連接讀服務器進行處理 如果不是 我們連接寫服務器進行處理
思路有了 那么就是代碼了
1 $querystr = strtolower(trim(substr($sql,0,6))); //截取SQL語句字符串 2 3 //如果是select,就連接slave(從)服務器 4 if($querystr == 'select') 5 { 6 $slave_server='192.168.80.3::3306'; 7 $dsn="mysql:host=$slave_server;dbname=3d"; 8 $user='root'; 9 $pass='root'; 10 $dbh=new PDO($dsn, $user, $pass); 11 $res=$dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC); 12 } 13 //如果不是select,就連接master(主)服務器 14 else 15 { 16 $master_server='192.168.33.22::3306'; 17 $dsn="mysql:host=$master_server;dbname=3dprintsys"; 18 $user='root'; 19 $pass='123456'; 20 $dbh=new PDO($dsn, $user, $pass); 21 $res=$dbh->exec($sql); 22 }
上面的代碼流程已經很清晰了 下面把代碼整理為面向對象風格
1 <?php 2 class Db 3 { 4 private $res; 5 function __construct($sql) 6 { 7 $querystr = strtolower(trim(substr($sql,0,6))); //截取SQL語句字符串 8 //如果是select,就連接slave(從)服務器 9 if($querystr == 'select') 10 { 11 $res=$this->slave ($sql); 12 $this->res=$res; 13 } 14 //如果不是select,就連接master(主)服務器 15 else 16 { 17 $res=$this->master ($sql); 18 $this->res=$res; 19 } 20 } 21 22 /** 23 * slave從庫返回sql查詢結果 24 * @param $sql 25 * @return array 26 */ 27 private function slave ($sql){ 28 //由於現實中讀服務器的數量可能在一個以上 會引出負載均衡問題 這里就不做闡述了 從服務器IP我就隨機獲取了 29 $slave_ip=$this->get_slave_ip(); 30 $dsn="mysql:host=$slave_ip;dbname=test"; 31 $user='root'; 32 $pass='root123'; 33 $dbh=new PDO($dsn, $user, $pass); 34 return $dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC); 35 } 36 37 /**master主庫返回sql執行結果 38 * @param $sql 39 * @return int 40 */ 41 private function master ($sql){ 42 $master_ip='192.168.80.3'; 43 $dsn="mysql:host=$master_ip;dbname=test"; 44 $user='root'; 45 $pass='root123'; 46 $dbh=new PDO($dsn, $user, $pass); 47 return $dbh->exec($sql); 48 } 49 50 /** 51 * 隨機獲取slave-ip 52 * @return mixed 53 */ 54 private function get_slave_ip(){ 55 $slave_ips=['192.168.0.1','192.168.0.2']; 56 $count=count($slave_ips)-1; 57 $index =mt_rand(0,$count); 58 return $slave_ips[$index]; 59 } 60 61 /** 62 * 獲取結果 63 * @return int 64 */ 65 public function get_res(){ 66 return $this->res; 67 } 68 } 69 70 $sql1 = "select * from ecs_goods_info "; 71 $sql2 = "insert into ecs_goods_info (goods_name) values ('haha')"; 72 $sql3 = "delete from ecs_goods_info where id=199"; 73 $sql4 = "update ecs_goods_info set goods_name='金剛葫蘆娃' where id=198"; 74 75 $db = new Db($sql1); 76 //$db = new Db($sql2); 77 //$db = new Db($sql3); 78 //$db = new Db($sql4); 79 80 var_dump($db->get_res()); 81
因為讀寫分離是建立在主從復制的基礎上 所以下次為大家分享下主從復制的原理