thinkphp下MySQL資料庫讀寫分離程式碼剖析?使用者8341957121592020-10-30 19:33:18

當採用原生態的sql語句進行寫入操作的時候,要用execute,讀操作要用query。萊垍頭條

MySQL資料主從同步還是要靠MySQL的機制來實現,所以這個時候MySQL主從同步的延遲問題是需要最佳化,延遲時間太長不僅影響業務,還影響使用者體驗。頭條萊垍

thinkphp核心類Thinkphp/library/Model。class。php 中,query 方法萊垍頭條

呼叫Thinkphp/library/Think/Db/Driver/Mysql。class。php萊垍頭條

/**萊垍頭條

* SQL查詢萊垍頭條

* @access public萊垍頭條

* @param string $sql SQL萊垍頭條

* @param mixed $parse 是否需要解析SQL 條萊垍頭

* @return mixed萊垍頭條

*/萊垍頭條

public function query($sql,$parse=false) {萊垍頭條

if(!is_bool($parse) && !is_array($parse)) {萊垍頭條

$parse = func_get_args();垍頭條萊

array_shift($parse);條萊垍頭

}頭條萊垍

$sql = $this->parseSql($sql,$parse);頭條萊垍

return $this->db->query($sql);萊垍頭條

}垍頭條萊

呼叫Thinkphp/library/Think/Db/Driver/Mysql。class。php萊垍頭條

/**萊垍頭條

* 執行查詢 返回資料集頭條萊垍

* @access public頭條萊垍

* @param string $str sql指令頭條萊垍

* @return mixed條萊垍頭

*/條萊垍頭

public function query($str) {垍頭條萊

if(0===stripos($str, ‘call’)){ // 儲存過程查詢支援萊垍頭條

$this->close();萊垍頭條

$this->connected = false;萊垍頭條

}條萊垍頭

$this->initConnect(false);萊垍頭條

if ( !$this->_linkID ) return false;萊垍頭條

$this->queryStr = $str;萊垍頭條

//釋放前次的查詢結果萊垍頭條

if ( $this->queryID ) { $this->free(); }萊垍頭條

N(‘db_query’,1);萊垍頭條

// 記錄開始執行時間條萊垍頭

G(‘queryStartTime’);萊垍頭條

$this->queryID = mysql_query($str, $this->_linkID);條萊垍頭

$this->debug();條萊垍頭

if ( false === $this->queryID ) {垍頭條萊

$this->error();萊垍頭條

return false;萊垍頭條

} else {條萊垍頭

$this->numRows = mysql_num_rows($this->queryID);萊垍頭條

return $this->getAll();萊垍頭條

}頭條萊垍

}萊垍頭條

上面初始化資料庫連結時,initConnect(false),呼叫Thinkphp/library/Think/Db/Db。class。php,注意false、true程式碼實現。true表示直接呼叫主庫,false表示呼叫讀寫分離的讀庫。萊垍頭條

/**頭條萊垍

* 初始化資料庫連線條萊垍頭

* @access protected萊垍頭條

* @param boolean $master 主伺服器垍頭條萊

* @return void條萊垍頭

*/萊垍頭條

protected function initConnect($master=true) {萊垍頭條

if(1 == C(‘DB_DEPLOY_TYPE’))垍頭條萊

// 採用分散式資料庫條萊垍頭

$this->_linkID = $this->multiConnect($master);萊垍頭條

else萊垍頭條

// 預設單資料庫萊垍頭條

if ( !$this->connected ) $this->_linkID = $this->connect();萊垍頭條

}條萊垍頭

/**萊垍頭條

* 連線分散式伺服器頭條萊垍

* @access protected萊垍頭條

* @param boolean $master 主伺服器萊垍頭條

* @return void萊垍頭條

*/萊垍頭條

protected function multiConnect($master=false) {萊垍頭條

foreach ($this->config as $key=>$val){萊垍頭條

$_config[$key] = explode(‘,’,$val);萊垍頭條

} 條萊垍頭

// 資料庫讀寫是否分離萊垍頭條

if(C(‘DB_RW_SEPARATE’)){垍頭條萊

// 主從式採用讀寫分離萊垍頭條

if($master)萊垍頭條

// 主伺服器寫入萊垍頭條

$r = floor(mt_rand(0,C(‘DB_MASTER_NUM’)-1));垍頭條萊

else{條萊垍頭

if(is_numeric(C(‘DB_SLAVE_NO’))) {// 指定伺服器讀萊垍頭條

$r = C(‘DB_SLAVE_NO’);萊垍頭條

}else{垍頭條萊

// 讀操作連線從伺服器頭條萊垍