Yii 数据库分表

Yii 的  CActiveRecord 是不支持数据库分表的,并且采用 className <—-> 数据表 一一对应的方式,所以你很难通过动态修改表名来实现分表。


我们这里的原则是,不动 Yii 任何现有的代码(为了以后跟随 Yii 升级的考虑),所以只能在我们自己的程序里面下功夫。


所谓分表,其实就是有一组 结构一模一样的表,它们唯一的区别就是表的名字不一样。所以我们这里想到了设计模式中的 Factory 模式。


下面是我们的实现,假如有一个表 article_content 结构,物理上有多个结构一样的表,名字为 article_content0, article_content1, article_content2, ….


我们首先用 Gii 模块自动生成 article_content 这个 Model ,如下:


基本的 article_content ModelPHP


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

class ArticleContent extends CActiveRecord

{

 

    /**

     * Returns the static model of the specified AR class.

     * @param string $className active record class name.

     * @return ArticleContent the static model class

     */

    public static function model($className=__CLASS__)

    {

        return parent::model($className);

    }

 

    /**

     * @return string the associated database table name

     */

    public function tableName()

    {

        return '{{article_content}}';

    }    

 

       // 后面代码省略

接下来,我们有几个物理分表,就建立几个 Model (注意这里的 Model 继承于 ArticleContent,只是简单的重载了 tableName 方法,其它都不需要实现)


ArticleContent0.php 文件PHP


1

2

3

4

5

6

7

8

class ArticleContent0 extends ArticleContent

{

    public function tableName()

    {

        return '{{article_content0}}';

    }    

 

}

 


ArticleContent1.php 文件PHP


1

2

3

4

5

6

7

8

class ArticleContent1 extends ArticleContent

{

    public function tableName()

    {

        return '{{article_content1}}';

    }    

 

}

注意我们这里的命名规范, 数据表名为  article_content1 对应的 class 和文件名为  ArticleContent1 ,通过这个命名规范我们就可以利用 Factory 模式来实现分表访问。


下面是我们设计的 Factory 模式,自动根据你的参数 来生成对应的 Model


Factory 模式实现自动根据表名建立对应的 ModelPHP


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

class PartitionTableFactory {

 

    public static function getTableModel($tableName){

 

        if (empty($tableName)){

            return  null;

        }

 

        // construct class name

        $itemArray = explode('_',$tableName);

 

        if(empty($itemArray)){

            return null;

        }

 

        // capitalize the first character

        $className = '';

        foreach ($itemArray as $item){

            $className .= ucfirst($item);

        }

 

        return new $className;

    }

}

有了 Factory 模式,我们编程使用就简单了,使用方法如下:


使用分表的方式PHP


1

2

3

4

5

6

7

8

9

10

// 这里根据上一级的参数决定应该把数据放到哪个分表中,用 Factory 自动生成对应分表的 Model

$articleContent = PartitionTableFactory::getTableModel($articleTitle->content_table_name);

 

$articleContent->title_id = $articleTitle->id;

$articleContent->sequence_id = $articleTitle->content_count;

$articleContent->url = $pipelineContext->fetchPageUrl;

$articleContent->content = $authorArticleItem['content'];

$articleContent->hash = $hashValue;

 

$articleContent->save();

这里的实现方法并不完美,毕竟每多一个物理分表,就需要多建一个 ArticleContent(N)  的 model,但是这个方法目前使用起来还算简单,同时不需要对 Yii 做任何修改,方便日后升级 Yii 框架。


要完美的方法,只能希望将来某天 Yii 能够假如对 分库分表 的实现 ,那我们就不用这么麻烦了。


 


转载于:https://my.oschina.net/yonghan/blog/533059

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值