关于多数据库的数据汇总时的各种思路

  • 如果不存在多库数据排序的情况下,只要将多库的数据整合到一起分页即可。做这种需求的时候先后想了以下的解决方案。下面均以A,B两个库举例。
    1)把A,B库的数据全部取出来放到内存,用内存进行分页。这个想法简单粗暴,要是查询的数据量少的话,这样做也简单,一旦数据量大的话,很显然,OutOfMemory内存吃不消。这种思路的话对于数据量小的多库来说应该是好的。
    2)奈何项目数据量大,那总要想着怎么尽量少的往内存里放数据而不导致内存溢出:
    假如每页为10条数据(row=10),那么查询第一页的数据的时候是分别从A,B两个库 select limit
    0,10,将取出来的20条放到内存截取前10条返回给页面。 第二页的时候则select limit
    0,20,将取出来的40条放到内存截取返回给页面。以此类推
    这个分页的策略其实是和第一个的存内存分页一样的,都是放到内存做切分,只是查询前面几页的时候,查询的数据量会少很多,放进内存的数量也会少,实际使用时,越后面命中率越低,但越到后面也就越接近第一种做法。整体来说,比第一张稍微好点。
    3)怎么样能让多库中取的每页数据更精确呢。每次取的时候尽量取所需要的数量。 已A库为起点,page
    为当前页码,row为每页行数,先判断B库是否有数据
 if(total>0){
                    //二库有值时取toal计算整体的总数
                    total = total_a + total_b;
                    //当一库的total大于等于当前页的数量时,只走一库分页
                    if(total_b >= (page * row) ) {
                            return getPage(row_a);
                    }
                    //当当前页请求数量超出一库total的时候,开始从二库取
                    else {
                        //如果临界页的数据数量刚好等于一库的total,即一库的total刚好被整除分页,那么记录一库走了几页,剩下的在二库中加上偏移页数,全部走二库分页
                        if(total_a % row == 0){
                            int x = total_a / row + 1;
                            Page.setPage(page - x);
                            Page.setRows(row);
                            row_b = B.get(Page);
                            return getPage(row_b);
                        }
                        //如果临界页存在一库和二库的merge数据
                        else {
                            //如果当前页码刚好在临界页,那从二库的第一页开始取,并和一库的数据merge取,截取对应的row行返回
                            if (total_a< (page * row) && total_a > ((page - 1) * row)) {
                                row_a.addAll(row_b);//row_b为第一页前10条,在返回时截掉
                                return getPage(row_a.subList(0, row_a.size() > row ? row : rows.size()));
                            }
                            //如果当前页码超过了临界页,开始全走二库
                            else {
                                //记录偏移页码
                                int x = total_a / row + 1;
                                //记录偏移merge过程每页中偏移的数量
                                int pos = x * row - total_a;
                                //新库减去偏移页重新从第一页开始取数据
                                Page.setPage(page - x);
                                //每次取row+pos的条记录
                                Page.setRows(row + pos);
                                //第一页的截取pos值之后的row行
                                if (Page.getPage() == 1) {
                                    row_b =B.get(Page);
                                    return getPage(row_b.subList(pos, row_b.size()), total).toJSONString();
                                }
                                //第二页以后截取前row行
                                else {
                                    //实际需要的数据开始index
                                    int start_index = (Page.getPage() -1) * row +pos;
                                    //实际需要的数据结束index
                                    int end_index = Page.getPage() * row +pos;
                                    //偏移区间需的开始index
                                    int start_pos =(Page.getPage()-1) * sr.getRows();
                                    //偏移区间需的结束index
                                    int end_pos = Page.getPage() * Page.getRows();
                                //如果实际的取的数据在偏移区间中,直接从当前偏移区间截取,这是第二页的
                                    if(start_index>= start_pos){
                                        row_b = B.get(Page);//这时候第一页还有后面一截row行没取完
                                        return getPage(row_b.subList(start_index-start_pos, end_index-start_pos >list1.size()? list1.size() : end_index-start_pos));
                                    }
                                    //如果start_index < start_pos,取前后两组数据,这是第二页之后的
                                    else if(start_index < start_pos){
                                        //页码回迁
                                        int fix_page = (Page.getPage()-1) * pos / Page.getRows() +1;
                                        Page.setPage(Page.getPage() - fix_page);
                                        row_b = B.get(Page);//这是第一页的,还有部分在下一页没取完
                                        Page.setPage(Page.getPage() + 1);
                                        row_b.addAll(B.get(Page));
                                        //再根据偏移进行截取
                                        int s_index = start_index - (Page.getPage()-fix_page -1 ) * sr.getRows();
                                        int s_end = end_index - (Page.getPage()-fix_page -1 )*sr.getRows();
                                        return getPage(row_b.subList(s_index, s_end>list1.size()? list1.size() : s_end ));
                                    }

                                }
                            }
                        }
                    }
                }

大致是分情况记录各种偏移,然后修正。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值