关于多数据库的数据汇总时的各种思路
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库是否有数据
大致是分情况记录各种偏移,然后修正。
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 )); } } } } } }
大致是分情况记录各种偏移,然后修正。
相关文章推荐
- Android之获取手机上的图片和视频缩略图thumbnails
- 数据库链接字符串查询网站
- DB2实例管理
- DB2实例管理
- Patrol 7 架构下?的处理方法
- 保障MySQL数据安全的14个最佳方法
- mysql问答汇集
- more、less 和 most 的区别
- 第三章 数据库备份和还原
- 创建一个空的IBM DB2 ECO数据库的方法
- Access 2000 数据库 80 万记录通用快速分页类
- 中病毒后常用的解决方法病毒终极解决方案
- IE7降低内存和降低CPU的几个技巧
- 开通一个数据库失败的原因的和解决办法
- 一个简单的asp数据库操作类
- CentOS下DB2数据库安装过程详解
- EasyASP v1.5发布(包含数据库操作类,原clsDbCtrl.asp)第1/2页
- sql2008 还原数据库解决方案
- AJAX实现瀑布流触发分页与分页触发瀑布流的方法