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

来源:互联网 发布:淘宝客单价是什么意思 编辑:程序博客网 时间:2024/05/07 17:33
  • 如果不存在多库数据排序的情况下,只要将多库的数据整合到一起分页即可。做这种需求的时候先后想了以下的解决方案。下面均以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
原创粉丝点击