最近一个项目,数据量有点大,使用分库+分表存储数据的,现在读取数据需要用到分页,有需要合并表。
写了2个方案:
一个是分页功能全部重写了,没有用yii2自带的分页数据处理插件:
先计算出条件范围内总共使用哪几个表。我是按时间查询的,所以如果是多个表只对第一个表条件时间大于起始时间,最后一个表时间小于结束时间(单表就没有这么多事情了)。
计算出每个表数据量。加起来为总数据。结果除以每页显示数据得到总页码
按偏移量(页码*每页显示数据)得到数据再哪个表,直接到对应表查询数据并显示,如果在多个表,每个一不分数据,先取第一个表的数据,然后对比第二表总数据和剩余数据量,进行迭代处理(其实正常情况肯定是只会存在2个表,不会大于2个表)。
然后使用一个单独的分页插件就好数据自己拼接。分页插件view页面写法
// 显示分页
echo \yii\widgets\LinkPager::widget([
'pagination' => $pagination,
'firstPageLabel' => '首页',
'lastPageLabel' => '尾页',
]);
第二个是偷懒的办法,直接使用 ActiveDataProvider 分页:
这个插件,查看源代码可以发现是可以设置数据库的,写法很简单
$dataProvider = new ActiveDataProvider([
'query' => $query,
'db' => db1,
'sort' => [
'defaultOrder' => [
'id' => SORT_DESC,
],
],
]);
直接写db就可以了,这个是数据库问题。
然后是多个表合并一个的问题,可以使用union,
$data = new Data();
$queryAll = $data->find()->from($tableList[0]);
for ($j = 1; $j < $ct; $j++){
$data = new Data();
$query = $data->find()->from($tableList[$j]);
$queryAll = $queryAll->union($query);
}
$query = (new Query())->from([$queryAll])
这样得到的query可以正常分页使用。
对啦上面的Data()是分表数据的model,是动态表明,网上有很多写法,可以自行百度一下。或者看我的另一个文章写的:https://blog.csdn.net/u012533474/article/details/86362598。
后面加from对象是query对象中实际上是没有把表名称记住,必须写到from里面,不然表不对的哦,然后就得不到数据,当然如果你写的Data模型可以实现的话,也可以不用写这里,写到Data里面。我就懒得改了。
其实数据量大建议使用第一种,自己写,用插件简单点,但是效率可能没那么好,数据过大会出问题的哦,前期可以先用这个过度一下,后面再慢慢优化。