请选择 进入手机版 | 继续访问电脑版

SpeedPHP框架

 找回密码
 注册成为新用户

QQ登录

只需一步,快速开始

查看: 8672|回复: 1

[数据模型] 多数据库/数据表切换与主从读写分离

[复制链接]
发表于 2012-8-4 22:52:19 | 显示全部楼层 |阅读模式

从SpeedPHP第三版开始,支持多种类型的数据库类型,并且通过对数据库句柄的操作,可以在多个数据库/数据表直接进行切换,也可以做到一定程度的“主从数据库读写分离”。

多数据库切换

主要是通过对spModel子类的_db成员变量进行切换操作。_db变量是数据库驱动类的实例,我们可以先直接实例化多个数据库类,然后再对_db变量进行赋值,就可以达到切换数据库的目的。

  1. // MSSQL驱动实例
  2. $dsn_mssql = spClass('db_mssql',array( 'MSSQL的配置'), SP_PATH.'/Drivers/mssql.php', TRUE);
  3. // MYSQL驱动实例
  4. $dsn_mysql = spClass('db_mysql',array( 'MYSQL的配置'), SP_PATH.'/Drivers/mysql.php', TRUE); // MYSQL

  5. // 实例化
  6. $g = spClass('m_guestbook');
  7. // 切换到MSSQL
  8. $g->_db = $dsn_mssql;
  9. /*****
  10. * 对MSSQL的操作
  11. ****/

  12. // 切换回MYSQL
  13. $g->_db = $dsn_mysql;
  14. /*****
  15. * MySQL的操作
  16. ****/
复制代码
本文所述的“库配置”,指的是spConfig配置中“db”节点的配置(数组)。
  1. 库配置 = array(  // 数据库连接配置
  2.         'driver' => 'mysql',   // 驱动类型
  3.         'host' => 'localhost', // 数据库地址
  4.         'port' => 3306,        // 端口
  5.         'login' => 'root',     // 用户名
  6.         'password' => '',      // 密码
  7.         'database' => '',      // 库名称
  8.         'prefix' => '',           // 表前缀
  9.         'persistent' => FALSE,    // 是否使用长链接
  10. );
复制代码
主从数据库读写分离

主从库读写分离主要是通过数据库中间层实现的,当然通过SpeedPHP框架,我们也可以在一定程度上做到读写分库。

  1. <?php
  2. class spModelNew extends spModel {
  3.         var $_db_write = null;
  4.         var $_db_read = null;
  5.        
  6.         var $db_master = array(
  7.                 'driver' => 'mysqli',   // 驱动类型
  8.                 'host' => 'localhost', // 数据库地址
  9.                 'port' => 3306,        // 端口
  10.                 'login' => 'root',     // 用户名
  11.                 'password' => '',      // 密码
  12.                 'database' => 'dbmaster',      // 库名称
  13.         );
  14.        
  15.         var $db_slave = array(
  16.                 'driver' => 'mysqli',   // 驱动类型
  17.                 'host' => 'localhost', // 数据库地址
  18.                 'port' => 3306,        // 端口
  19.                 'login' => 'root',     // 用户名
  20.                 'password' => '',      // 密码
  21.                 'database' => 'dbslave',      // 库名称
  22.         );
  23.        
  24.         public function __construct(){
  25.                 if( null == $this->tbl_name )$this->tbl_name = $GLOBALS['G_SP']['db']['prefix'] . $this->table;
  26.                 // 主库(写入库)实例化驱动
  27.                 $this->_db_write = spClass('db_mysqli', array($this->db_master), SP_PATH.'/Drivers/mysqli.php', true);
  28.                 // 从库(读取库)实例化驱动
  29.                 $this->_db_read = spClass('db_mysqli', array($this->db_slave), SP_PATH.'/Drivers/mysqli.php',true);
  30.         }


  31.         public function find($conditions = null, $sort = null, $fields = null){
  32.                 $this->_db = $this->_db_read;
  33.                 return parent::find($conditions, $sort, $fields);
  34.         }
  35.         public function findAll($conditions = null, $sort = null, $fields = null, $limit = null){
  36.                 $this->_db = $this->_db_read;
  37.                 return parent::findAll($conditions, $sort, $fields, $limit);
  38.         }
  39.         public function findBy($field, $value){
  40.                 $this->_db = $this->_db_read;
  41.                 return parent::findBy($field, $value);
  42.         }
  43.         public function findSql($sql){
  44.                 $this->_db = $this->_db_read;
  45.                 return parent::findSql($sql);
  46.         }
  47.         public function findCount($conditions = null){
  48.                 $this->_db = $this->_db_read;
  49.                 return parent::findCount($conditions);
  50.         }


  51.         public function create($row){
  52.                 $this->_db = $this->_db_write;
  53.                 return parent::create($row);
  54.         }
  55.         public function createAll($rows){
  56.                 $this->_db = $this->_db_write;
  57.                 return parent::createAll($row);
  58.         }
  59.         public function delete($conditions){
  60.                 $this->_db = $this->_db_write;
  61.                 return parent::delete($conditions);
  62.         }
  63.         public function updateField($conditions, $field, $value){
  64.                 $this->_db = $this->_db_write;
  65.                 return parent::updateField($conditions, $field, $value);
  66.         }
  67.         public function runSql($sql){
  68.                 $this->_db = $this->_db_write;
  69.                 return parent::runSql($sql);
  70.         }
  71.         public function affectedRows(){
  72.                 $this->_db = $this->_db_write;
  73.                 return parent::affectedRows();
  74.         }
  75.         public function update($conditions, $row){
  76.                 $this->_db = $this->_db_write;
  77.                 return parent::update($conditions, $row);
  78.         }
  79.         public function replace($conditions, $row){
  80.                 $this->_db = $this->_db_write;
  81.                 return parent::replace($conditions, $row);
  82.         }
  83.         public function incrField($conditions, $field, $optval = 1){
  84.                 $this->_db = $this->_db_write;
  85.                 return parent::incrField($conditions, $field, $optval);
  86.         }
  87.         public function decrField($conditions, $field, $optval = 1){
  88.                 $this->_db = $this->_db_write;
  89.                 return parent::decrField($conditions, $field, $optval);
  90.         }
  91.         public function deleteByPk($pk){
  92.                 $this->_db = $this->_db_write;
  93.                 return parent::deleteByPk($pk);
  94.         }
  95. }
复制代码

从上面的类,我们继承了spModel的大部分操作,并且区分开“读”与“写”的操作,然后在构造函数中,我们分别实例化了“读库”和“写库”的数据库驱动。最后我们在每个“读操作”中,将“读库”的实例赋值给spModel的_db变量,那么这些“读操作”就都会去读取“读库”的数据;而每个“写操作”也通过将“写库”的实例赋值给_db后,“写操作”就会对“写库”进行操作了。

在应用程序中,其他的数据库模型类都应该继承于spModelNew(而不是spModel),这样就可以无缝地使用“读写分库”的功能了。


 楼主| 发表于 2016-6-22 10:56:14 | 显示全部楼层
多库切换例子下载: mutildb.7z (896.53 KB, 下载次数: 44)
您需要登录后才可以回帖 登录 | 注册成为新用户

本版积分规则

手机浏览|简版|中文PHP框架|开源协议|SpeedPHP.com ( 粤ICP备08008671号

GMT+8, 2020-2-19 18:28

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表