2014-02-12 35 views
0

我在MySQL環境中有一些分片表。我使用Yii,所以我想爲分片添加一些支持。我已成功地創建自定義的CActiveRecord類是母親所有的分片型號:CActiveRecord工會

class ShardedActiveRecord extends CActiveRecord{ 
    private $_shard; 

    public function tableName(){ 
     return get_class($this) . $this->getShard(); 
    } 


    public function setShard($shard) { 
     $this->_shard = $shard; 
     call_user_func(array(get_class($this), 'model'))->_shard = $shard; 

     $this->refreshMetaData(); 

     return $this; 
    } 

    public function getShard() { 
     if($this->_shard === null){ 
      $this->setShard(""); 
     } 
     return $this->_shard; 
    } 

    public function createShardedTable($shard){ 
     $connection=Yii::app()->db; 
     $command = $connection->createCommand("CREATE TABLE IF NOT EXISTS ".get_class($this).$shard." LIKE ".get_class($this)); 
     $command->execute(); 
    } 
} 

一切工作的精細插入,但是當我需要找回一些數據,我不知道如何着手。我希望在我的模型中有一個參數,這個參數可以是分片的表格。這裏有一個我想成爲可能的例子:

MyModel :: model() - > shard(「01,」02「,03」) - > findAll();

而最終是回到過去的3個表:

$數據=新CActiveDataProvider( 「爲MyModel」)

的SQL檢索數據,如果我shoold這個樣子要選擇的前3個表:

SELECT * FROM stats01 
UNION SELECT * FROM stats02 
UNION SELECT * FROM stats03 

我試圖重新定義fetchData()函數,但它沒有工作,重新定義的函數並沒有改變數據集...我需要把所有的數據看作一個大塊,就好像它是一個表。

謝謝!

回答

0

更新:

我找到了一個解決問題的辦法。我在ShardedActiveRecord類中創建了一個函數,該類生成一個自定義CActiveRecord並將其返回。下面是它的外觀:

public function getMergedDataProvider($back){ 
     $modelArray = array(); 
     $model = array(); 
     $now = date("Ym"); 

     for($i=0; $i<$back; $i++){ 
      array_push($modelArray, $this->model()->setShard(date("Ym", strtotime("-".$i." month", strtotime($now))))->findAll()); 
     } 

     foreach($modelArray as $ma){ 
      $model = array_merge($model, $ma); 
     } 

     $dataProvider = new CActiveDataProvider(get_class($this), array(
      'data'=>$model, 
     )); 

     return $dataProvider; 
    } 

我添加了一個參數,讓我去獲得最後3個表碎片(他們是相對的日期)。

在需要使用分片模式的行動,我可以調用函數的話,並把它作爲一個正常的CActiveDataProvider:

$數據提供程序=爲MyModel ::模型() - > getMergedDataProvider (3);

我希望這會幫助別人!