Maison >développement back-end >tutoriel php >Explication détaillée de la séparation en lecture et en écriture de la base de données MySQL sous thinkphp

Explication détaillée de la séparation en lecture et en écriture de la base de données MySQL sous thinkphp

墨辰丷
墨辰丷original
2018-05-23 17:13:401493parcourir

Cet article présente principalement l'analyse du code de séparation lecture-écriture de la base de données MySQL sous thinkphp. Les amis intéressés peuvent s'y référer.

Lors de l'utilisation de l'instruction SQL d'origine pour les opérations d'écriture, l'exécution est utilisée et la requête est utilisée pour les opérations de lecture.

La synchronisation maître-esclave des données MySQL repose toujours sur le mécanisme MySQL, donc le problème de retard de la synchronisation maître-esclave MySQL doit être optimisé à ce moment-là. Si le délai est trop long, ce n'est pas le cas. affecte uniquement l'entreprise, mais affecte également l'expérience utilisateur.

Dans la classe principale de thinkphp Thinkphp/library/Model.class.php, la méthode de requête appelle 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);
  }

Appelez 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();
    }
  }

Lors de l'initialisation du lien de base de données ci-dessus, initConnect(false) appelle Thinkphp/library/Think/Db/Db.class.php, faites attention à l'implémentation du code faux et vrai. true signifie appeler directement la bibliothèque principale, false signifie appeler la bibliothèque de lecture avec une lecture et une écriture séparées.

  /**
   * 初始化数据库连接
   * @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{
          // 读操作连接从服务器
          $r = floor(mt_rand(C('DB_MASTER_NUM'),count($_config['hostname'])-1));  // 每次随机连接的数据库
        }
      }
    }else{
      // 读写操作不区分服务器
      $r = floor(mt_rand(0,count($_config['hostname'])-1));  // 每次随机连接的数据库
    }
    $db_config = array(
      'username' => isset($_config['username'][$r])?$_config['username'][$r]:$_config['username'][0],
      'password' => isset($_config['password'][$r])?$_config['password'][$r]:$_config['password'][0],
      'hostname' => isset($_config['hostname'][$r])?$_config['hostname'][$r]:$_config['hostname'][0],
      'hostport' => isset($_config['hostport'][$r])?$_config['hostport'][$r]:$_config['hostport'][0],
      'database' => isset($_config['database'][$r])?$_config['database'][$r]:$_config['database'][0],
      'dsn'    => isset($_config['dsn'][$r])?$_config['dsn'][$r]:$_config['dsn'][0],
      'params'  => isset($_config['params'][$r])?$_config['params'][$r]:$_config['params'][0],
      'charset'  => isset($_config['charset'][$r])?$_config['charset'][$r]:$_config['charset'][0],      
    );
    return $this->connect($db_config,$r);
  }

le paramètre de méthode de requête est faux, sinon supprimez, mettez à jour et ajoutez la bibliothèque principale de lecture. Cela peut être combiné avec les opérations de suppression, de sauvegarde et d'ajout dans Thinkphp/library/Model.class.php, et le paramètre est vrai.

Ce qui précède représente l’intégralité du contenu de cet article, j’espère qu’il sera utile à l’étude de chacun.


Recommandations associées :

PHPAnalyse de la méthode de la fonction shuffle() pour prélever plusieurs éléments aléatoires d'un Compétences array_php

PHPUtilisez stream_context_create() pour simuler les astuces POST/GET requêtes_php

PHPComment convertir XML en tableau_php conseils

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn