当查询的数据来自多个数据源,有哪些好的分页策略?
程序员文章站
2022-11-22 10:17:07
概述 在业务系统开发中,尤其是后台管理系统,列表页展示的数据来自多个数据源,列表页需要支持分页,怎么解决? 问题 如上图,数据源可能来自不同 DB 数据库,可能来自不同 API 接口,也可能来自 DB 和 API 的组合。 我这也没有太好的解决方案,接到这样的需求,肯定首先和需求方沟通,这样分页是否 ......
概述
在业务系统开发中,尤其是后台管理系统,列表页展示的数据来自多个数据源,列表页需要支持分页,怎么解决?
问题
如上图,数据源可能来自不同 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 u") } 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 } }
小结
如果你有更好的方案,欢迎留言评论 ~
推荐阅读
上一篇: python GIL