翻页技术实现(转)

原地址http://timyang.net/data/key-list-pagination/

Thursday, Dec 4th, 2014 by Tim | Tags: mysqlnosql

今天讨论了一个传统的问题,问题本身比较简单,就是针对key-list类型的数据,如何优化方案做到性能与成本的tradeoff。Key-list在用户类型的产品中非常普遍,如一个用户的好友关系 {“uid”:{1,2,3,4,5}},一条微博下面的评论id列表,一个用户发表的微博id列表等。

根据经验,在大部分场景下,单个业务的list数据长度99%在1000条以下,但剩下的1%的数据可能多达100万条,因此在实现方案的时候不能忽视这些超大数据集的问题,这也体现了常说的80%+的时间在优化20%-的功能。

List数据访问模型常见的有两种方式
1. 扶梯方式
扶梯方式在导航上通常只提供上一页/下一页这两种模式,部分产品甚至不提供上一页功能,只提供一种“更多/more”的方式,也有下拉自动加载更多的方式,在技术上都可以归纳成扶梯方式。

扶梯方式在技术实现上比较简单及高效,根据当前页最后一条的偏移往后获取一页即可。写成SQL可能类似

SELECT * FROM LIST_TABLE WHERE id > offset_id LIMIT n;

2. 电梯方式
另外一种数据获取方式在产品上体现成精确的翻页方式,如1,2,3……n,同时在导航上也可以由用户输入直达n页。国内大部分场景采用电梯方式,但电梯方式在技术实现上相对成本较高。
在MySQL中,通常提到的b-tree,在存储引擎实现上,通常都是b+tree,如图

从图中可以看到,使用电梯方式时候,当用户指定翻到第n页时候,并没有直接方法寻址到该位置,而是需要从第一楼逐个count,scan到count*page时候,获取数据才真正开始,所以导致效率不高。而在数据存在新增及删除的情况下,偏移量也不能有效的缓存,一个10万条的list,只要有一条变化,原先的楼层可能会全部发生变化。

以上描述的场景属于单机版本,在数据规模较大时候,互联网系统通常使用分库的方式来保存,实现方法更为复杂。
在面向用户的产品中,数据分片通常会将同一用户的数据存在相同的分区,以便更有效率的获取当前用户的数据。如下图所示

但上述方案在常见的场景中存在很大不足,大部分产品用户只访问最近产生的数据,历史的数据只有极小的概率被访问到,因此同一个区域内部的数据访问是非常不均匀,如图中2014年生成的属于热数据,2012年以前的属于冷数据,只有极低的概率被访问到。因此简单的解决方案是按时间远近将数据进行进一步分区,如图。

注意在上图中使用时间方式sharding之后,在一个时间分区内,也需要用前一种方案将数据进行sharding,因为一个时间片区通常也无法用一台服务器容纳。

上面的方案较好的解决了具体场景对于key list访问性能及成本的tradeoff,但是它存在以下不足

  • 数据按时间进行滚动无法全自动,需要较多人为介入或干预
  • 数据时间维度需要根据访问数据及模型进行精巧的设计,无法简单重用
  • 为了实现电梯直达功能,需要增加额外的二级索引,比如2013年某用户总共有多少条记录

由于以上问题,尤其是二级索引的引入,显然它不是理想中的key list实现,后文继续介绍适合长尾翻页key list设计的一些思路及尝试。

时间: 2024-08-29 02:20:28

翻页技术实现(转)的相关文章

为什么超长列表数据的翻页技术实现复杂

为什么超长列表数据的翻页技术实现复杂 http://timyang.net/data/key-list-pagination/ 今天讨论了一个传统的问题,问题本身比较简单,就是针对key-list类型的数据,如何优化方案做到性能与成本的tradeoff.Key-list在用户类型的产品中非常普遍,如一个用户的好友关系 {“uid”:{1,2,3,4,5}},表示uid包含有5个好友:一条微博下面的评论id列表{“weibo_id”: {comment_id1, comment_id2……}},一

Atitti usrQBf1801 翻页控件规范  v2

Atitti usrQBf1801 翻页控件规范  v2 1. 参考api  参考easyui ,.net系列的1 1.1. 翻页流程  初始化翻页控件,以及绑定新页面event onSelectPage2 1.2. 点击下一页2 1.3. 回调新页面时间获取数据,然后绑定在控件上们3 1.4. 翻页技术原理的的参考::4 1.1. 参考api  参考easyui ,.net系列的 翻页api应该参考easyui ,.net系列的 onSelectPage  (pageNumber, pageS

web前端课程技术内容之如何做一个简单的手机端页面的翻页

[如何做一个简单的手机端页面的翻页] 第一步:创建移动端页面内 HTML + CSS [注]可用弹性布局 但需要注意的是 外层盒子的定位 第二步: 思考问题 要实现怎样的效果? 1. 手指滑动时触发事件[左右]两个方向 2.点击footer部分的下标实现切换效果 3.点击footer部分的下标实现下标颜色变化 第三步:编写JS代码 添加监听事件 document.addEventListener('DOMContentLoaded',function(){ 创建一个数组用于调用数组属性值 或者

Atitit easyui翻页组件与vue的集成解决方案attilax总结

===============使用1 ===========\paggingUtil_easyui_vue.js2 C:\Users\Administrator\Desktop\00oa\js\paggingUtil_easyui_vue.js ===============使用 <!-- pagging--> <link rel="stylesheet" type="text/css" href="easyui1.5/themes/de

Atitit.pagging &#160;翻页功能解决方案专题 与 目录大纲 v3 r44.docx

Atitit.pagging  翻页功能解决方案专题 与 目录大纲 v3 r44.docx 1.1. 翻页的重要意义1 1.2. Dep废弃文档   paip.js翻页分页pageing组件.txt1 1.3. ---原理1 1.4. -------lib1 1.1.   翻页的重要意义 技术上,商业上,翻页都是一个非常高频率的功能.. 提升高频功能的效率,可以大力提升项目整体效率.. 效率优化的重要原则就是高频功能效率优化 1.2. Dep废弃文档   paip.js翻页分页pageing组件

【2017-02-05】【前端】百度贴吧免登陆查看评论,翻页等

前路漫漫,吾将上下而求索! 前言:百度贴吧只看楼主,翻页等可以通过复制链接实现,但是评论里面要查看更多就不行了.于是就来看看. 结论:console控制台里面执行 PageData.user.is_login=true; 执行前: 执行后: 过程: 本来想试试断点调试的,然而技术水平不足,click上下完断点后调试不出来.233,有大神的话跪求指点. 于是换种思路,这种业务逻辑,必然有个全局变量进行判断,于是遍历: for(var p in window){ console.log(p+'---

UIScrollView pagingEnabled自定义翻页宽度

PagingEnabled只能翻过整页,下面几个简单的设置即可实现 技术点: 1. 创建一个继承UIView的视图,并设置clipsToBounds= YES 2. 添加一个UIscrollView控件,将其宽度设置为自定义翻页的宽度 3. 设置UIScrollview 的clipsToBounds= NO 4. 确保本View的宽度大于UIScrollView的宽度用于显示预览内容 5. 重写本View的hittest方法,为了确保用户滑动UIscrollview以外的空间时也可以触发UIsc

万能js实现翻页,动态生成内容自动翻页,兼容各种浏览器(已测试)----神器版!

转--http://www.2cto.com/kf/201402/277535.html 万能js实现翻页,动态生成内容自动翻页,兼容各种浏览器(已测试)----神器版! 2014-02-11      0个评论    来源:卡布洛技术专栏   收藏    我要投稿 要求:动态输入内容,点击post生成内容条,实现自动翻页! 废话不多说,直接上代码: js代码: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25

织梦DEDECMS网站首页如何实现分页翻页

织梦DEDECMS模板网站首页如何实现首页分页和翻页 方法如下:(三种方法,自己选择一种来实现分页吧) 第一种:调用ajax和参数的(不推荐)1.必须在DEDE首页模板中的<head></head>中引入(详细看你的默认模板) <script language="javascript" type="text/javascript" src="{dede:global.cfg_cmsurl/}/include/dedeajax2