您的位置:首页 > 数据库

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

2016-06-22 12:46 246 查看
如果不存在多库数据排序的情况下,只要将多库的数据整合到一起分页即可。做这种需求的时候先后想了以下的解决方案。下面均以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 ));
}

}
}
}
}
}


大致是分情况记录各种偏移,然后修正。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息