当查询的数据来自多个数据源,有哪些好的分页策略?

栏目: IT技术 · 发布时间: 5年前

概述

在业务系统开发中,尤其是后台管理系统,列表页展示的数据来自多个数据源,列表页需要支持分页,怎么解决?

问题

当查询的数据来自多个数据源,有哪些好的分页策略?

如上图,数据源可能来自不同 DB 数据库,可能来自不同 API 接口,也可能来自 DB 和 API 的组合。

我这也没有太好的解决方案,接到这样的需求,肯定首先和需求方沟通,这样分页是否合理。

无非就两种方案:

  • 数据定期同步,首先将查询的数据汇总到一个地方,然后再进行查询分页。

  • 内存中分页,首先将 查询的 数据存放到内存中,然后再进行查询分页。

如果以某一数据源进行分页,其他字段去其他数据源获取,这样还好处理一些。

如果以多个数据源融合后再分页的话,就数据定期同步 或 内存中分页吧。

数据定期同步方案可以根据实际情况去设计同步频率,至于同步到 ES/MySQL/MongoDB 内部决定即可。

关于内存中分页方案,下面分享两个小方法,供参考。

PHP 方法

$data = [

0 => ['name' => "姓名1", 'age' => "年龄1"],

1 => ['name' => "姓名2", 'age' => "年龄2"],

2 => ['name' => "姓名3", 'age' => "年龄3"],

3 => ['name' => "姓名4", 'age' => "年龄4"],

4 => ['name' => "姓名5", 'age' => "年龄5"],

5 => ['name' => "姓名6", 'age' => "年龄6"],

6 => ['name' => "姓名7", 'age' => "年龄7"],

7 => ['name' => "姓名8", 'age' => "年龄8"],

8 => ['name' => "姓名9", 'age' => "年龄9"],

9 => ['name' => "姓名10", 'age' => "年龄10"],

];


/**

* 数组分页

* @param array $arrayData 数组数据

* @param int $page 第几页

* @param int $pageSize 每页展示条数

* @return array

*/

function arrayToPageData($arrayData = [], $page = 1, $pageSize = 10)

{

$arrayData = array_values((array)$arrayData);

$pageData['list'] = array_slice($arrayData, ($page - 1) * $pageSize, $pageSize);

$pageData['pagination']['total'] = count($arrayData);

$pageData['pagination']['currentPage'] = $page;

$pageData['pagination']['prePageCount'] = $pageSize;

return $pageData;

}


echo json_encode(arrayToPageData($data, 2, 3));

输出:

{

"list": [

{

"name": "姓名4",

"age": "年龄4"

},

{

"name": "姓名5",

"age": "年龄5"

},

{

"name": "姓名6",

"age": "年龄6"

}

],

"pagination": {

"total": 10,

"currentPage": 2,

"prePageCount": 3

}

}

Go 方法

package main


import (

"encoding/json"

"fmt"

)


type User []struct {

Name string `json:"name"`

Age string `json:"age"`

}


type Pagination struct {

Total int `json:"total"`

CurrentPage int `json:"currentPage"`

PrePageCount int `json:"prePageCount"`

}


type ListPageData struct {

List User `json:"list"`

Pagination Pagination `json:"pagination"`

}


func main() {

jsonStr := `[{"name": "姓名1","age": "年龄1"},

{"name": "姓名2","age": "年龄2"},

{"name": "姓名3","age": "年龄3"},

{"name": "姓名4","age": "年龄4"},

{"name": "姓名5","age": "年龄5"},

{"name": "姓名6","age": "年龄6"},

{"name": "姓名7","age": "年龄7"},

{"name": "姓名8","age": "年龄8"},

{"name": "姓名9","age": "年龄9"},

{"name": "姓名10","age": "年龄10"}

]`


var user User

err := json.Unmarshal([]byte(jsonStr), &user)

if err != nil {

fmt.Println(err.Error())

}


page := 2

pageSize := 3

pageData := ArraySlice(user, page, pageSize)


listPageData := ListPageData{}

listPageData.List = pageData

listPageData.Pagination.Total = len(user)

listPageData.Pagination.CurrentPage = page

listPageData.Pagination.PrePageCount = pageSize


jsonData, _ := JsonEncode(listPageData)

fmt.Println(jsonData)

}


func JsonEncode(v interface{}) (string, error) {

bytes, err := json.Marshal(v)

if err != nil {

return "", err

}

return string(bytes), nil

}


func ArraySlice(u User, page int, pageSize int) User {

offset := (page - 1) * pageSize

if offset > int(len(u)) {

panic("offset: the offset is less than the length of s")

}

end := offset + pageSize

if end < int(len(u)) {

return u[offset:end]

}

return u[offset:]

}

输出:

{

"list": [

{

"name": "姓名4",

"age": "年龄4"

},

{

"name": "姓名5",

"age": "年龄5"

},

{

"name": "姓名6",

"age": "年龄6"

}

],

"pagination": {

"total": 10,

"currentPage": 2,

"prePageCount": 3

}

}

小结

如果你有更好的方案,欢迎留言评论 ~

推荐阅读

当查询的数据来自多个数据源,有哪些好的分页策略?


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Reality Is Broken

Reality Is Broken

Jane McGonigal / Penguin Press HC, The / 2011-1-20 / USD 26.95

Visionary game designer Jane McGonigal reveals how we can harness the power of games to solve real-world problems and boost global happiness. More than 174 million Americans are gamers, and......一起来看看 《Reality Is Broken》 这本书的介绍吧!

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具