项目需要要为yii扩展多库和主从支持.
CDbConnection的pdo居然是private. 而且在CDbConnection里面也不是使用统一的getPdoInstance方法来取得PDO对象.而是直接$this->_pdo. 给扩展带来了很大的麻烦.
这个我也忍了. 1.1.8里面新增了pdoClass选项. 可看看createPdoInstance就知道.这个选项等于没有…
我要为PDO加一个壳.除了直接对yii原生代码下手之外. 我别无选择.
项目需要要为yii扩展多库和主从支持.
CDbConnection的pdo居然是private. 而且在CDbConnection里面也不是使用统一的getPdoInstance方法来取得PDO对象.而是直接$this->_pdo. 给扩展带来了很大的麻烦.
这个我也忍了. 1.1.8里面新增了pdoClass选项. 可看看createPdoInstance就知道.这个选项等于没有…
我要为PDO加一个壳.除了直接对yii原生代码下手之外. 我别无选择.
你如果用AR就很好解决,不需要对PDO怎么操作。
我的项目里面所有的操作都用AR,支持主从,不修改代码。全部的ar继承ActiveRecoder类
如有需要请加 群 40933125,不是为了宣传,主要没有网站。。呵呵
怎么从AR层面实现
多数据库支持. 也就是必须支持多个数据库.
主从. 每个数据库必须是独立的主从集群.
读写判定. 写操作入主库. 读操作去从库.
强制模式. 必须能够允许强制写入从库等等.
故障. 主库要有2个. 在一个出现故障时报警并由第二个接管. 从库故障要将读操作指向主库
从库的使用是随机的.
链接的复用. 当主从同为一个链接时. 链接必须复用.
Yii的组件要保证可用: CDbLogRoute / CDbDataProvider / CDbCommand 这些组件如何判断主从? 我并没有看到他们的数据是从AR来的.
如果要扩展多库和主从库,请仔细研究system.db包和system.db.schema包,个人觉得,重写这两部分就OK了,然后在config里面配置db的class就可以实现重写,没必要对原生代码动手,YII的扩展度很高的
楼上正解。
就是重写的那两部分啊. 基本要换掉整个db包.
如果官方对类里面的一些私有成员放宽到protected的话. 需要改动的更少. 我不是完全重写. 基本都是派生的.
除了派生. 几乎不可能替换掉原来的db包. 像Session啊. Log啊之类的. 单库存在的必要还是有的. 保留原有的db包要保险的多.
在他的基础上派生新类我觉得是最好的策略.
一些私有成员.
比如CDbConnection._pdo CDbConnection._active之类的. 这些限制成private实在是不方便. 不然的话能少写很多东西.
我只需要重写特定的方法就行了. 而不是这样大动干戈.
我就不明白,为什么非要去改pdo???
pdo会涉及到多库的操作?
可能我不知道的你的开发思路,但是我觉得如果你要扩展多库,那么只要重写connection类就行了
重写connection不足以满足需求.
首先读写分离是个问题. 你要针对不同的SQL语句去连接不同的数据库. 打个比方:
Yii::app()->db->createCommand('INSERT ...');
这里面是没有任何地方可以容许你指定你要操作的数据库是哪一个以及主从情况. 当然前提是如下:
db => array(
'mydb1' => array('master' => array('...', '...'), 'slaver' => array('...', '...'))
);
不知你能不能明白. 就是要支持多个数据库以及每个数据都有主从之分. 那么针对上面的操作是完全不可能实现的.
你没选择数据库
你没指定主从.
那么. 数据库的选择只能编码来实现了. 比如
Yii::app()->db->mydb1->createCommand('...');
但是主从呢?
这里你要自动判定主从. 因此重写CDbConnection不足以满足需求. 你需要重写CDbCommand类. 还有整个ActiveRecord包.
上面这也只是一部分. 有很多隐患在里面.
首先是last insert id. 因为涉及了主从. 所以在不指定主从的情况下你要知道上一条写入操作是针对谁的. 虽然我们大多数
情况下写入操作都是针对主库. 但写入从库的个例是有的. 因此last insert id你是要判定主从的.
那么问题来了. 在PDOStatement没有execute之前是不会产生id的. 如果你不为PDO加壳. 你怎么知道他是否被执行了?
需求大致可以归纳如下:
多库支持.
每个库都有各自的主从集群.
读写自动判定. 这个判定不仅仅是针对SQL语句的. 还有针对last insert id的.
保证原有Yii代码依然可用.就是在不改变已有编码的情况下. 挖地基来解决问题.
满足以上四点. 我觉得不大动干戈不行. 也许重写整个db包会有更优秀的解决办法. 但重写在我目前来看是不可能.
建议你先学习下面向对象的基础,再来大放厥词!变量的私有化正式为了方便维护和扩展!!附别人的多db 读写分离实现。Yii框架实现MySQL多库和主从分离
mark~~~~~~~~~