一、基于偏移的分頁
例如: http://XXXXXXXlist?page=1&count=20
缺點(diǎn):
1、數(shù)據(jù)重復(fù)
2、數(shù)據(jù)缺失
3、效率低
使用limit在數(shù)據(jù)量小的時候并不會有效率問題,但是當(dāng)數(shù)據(jù)偏移量很大時性能會開始急劇下降,查詢性能比對會在接下來提到。
綜上所述,流式分頁不需要也不適合使用傳統(tǒng)分頁,而是使用一種更合適的方法:游標(biāo)分頁。
所以這種分頁方法 適用于 數(shù)據(jù)部經(jīng)常變化的情況?;蛘吣玫綌?shù)據(jù)后做去重處理。
二、基于游標(biāo)分頁方案
基于游標(biāo)的分頁是最有效的分頁方法,應(yīng)盡量使用這種方法。游標(biāo)是指標(biāo)記數(shù)據(jù)列表中特定項(xiàng)目的一個隨機(jī)字符串。該項(xiàng)目未被刪除時,游標(biāo)將始終指向列表的同一部分,項(xiàng)目被刪除時游標(biāo)即失效。因此,您的應(yīng)用不應(yīng)存儲任何舊的游標(biāo),也不能假定它們?nèi)匀挥行А?/p>
游標(biāo)分頁的連線支持以下參數(shù):
before:這是指向已返回的數(shù)據(jù)頁面開頭的游標(biāo)。
after:這是指向已返回的數(shù)據(jù)頁面末尾的游標(biāo)。
limit:這是每個頁面返回的單獨(dú)對象的數(shù)量。請注意:這是上限。如果數(shù)據(jù)列表中沒有足夠的剩余對象,那么返回的數(shù)量將小于這個數(shù)。為提升性能,將為某些連線的 limit 值設(shè)置上限。在調(diào)用案例中,API 將返回正確的分頁鏈接。
next:將返回下一頁數(shù)據(jù)的圖譜 API 端點(diǎn)。如果未包含,則顯示的是最后一頁數(shù)據(jù)。根據(jù)分頁的可見性和隱私,頁面可能為空,但包含“next”分頁鏈接?!皀ext”鏈接不再出現(xiàn)時,應(yīng)停止分頁。
previous:將返回上一頁數(shù)據(jù)的圖譜 API 端點(diǎn)。如果未包含,則顯示的是第一頁數(shù)據(jù)。
Facebook 示例
{
"data":[ ...端點(diǎn)數(shù)據(jù)在此 ],
"paging":{
"cursors":{
"after":"MTAxNTExOTQ1MjAwNzI5NDE=",
"before":"NDMyNzQyODI3OTQw"
},
"previous":"https://graph.facebook.com/me/albums?limit=25&before=NDMyNzQyODI3OTQw",
"next":"https://graph.facebook.com/me/albums?limit=25&after=MTAxNTExOTQ1MjAwNzI5NDE="
}
}
Twitter 示例
請求參數(shù):
|參數(shù)| 是否可選| 描述 |
|:----|:-----||
|since_id|optional|Returns results with an ID greater than (that is, more recent than) the specified ID. There are limits to the number of Tweets which can be accessed through the API. If the limit of Tweets has occured since the since_id, the since_id will be forced to the oldest ID available. ** Example Values: 12345|
|count|optional|Specifies the number of tweets to try and retrieve, up to a maximum of 200 per distinct request. The value of count is best thought of as a limit to the number of tweets to return because suspended or deleted content is removed after the count has been applied. We include retweets in the count, even if include_rts is not supplied. It is recommended you always send include_rts=1 when using this API method.|
|max_id|optional|Returns results with an ID less than (that is, older than) or equal to the specified ID.Example Values: 54321**|
返回結(jié)果:
"search_metadata": {
"max_id": 250126199840518145,
"since_id": 24012619984051000,
"refresh_url": "?since_id=250126199840518145&q=php&result_type=recent&include_entities=1",
"next_results": "?max_id=249279667666817023&q=php&count=10&include_entities=1&result_type=recent",
"count": 10,
"completed_in": 0.035,
"since_id_str": "24012619984051000",
"query": "php",
"max_id_str": "250126199840518145"
}
問題: 如果 某一條 id 被刪除了,怎么處理?
三、基于時間的分頁
時間分頁使用指向數(shù)據(jù)列表中的特定時間的 Unix 時間戳在結(jié)果數(shù)據(jù)中導(dǎo)航。
基于時間的連線支持以下參數(shù):
- until:指向基于時間的數(shù)據(jù)范圍末尾的 Unix 時間戳或
strtotime
數(shù)據(jù)值。 - since:指向基于時間的數(shù)據(jù)范圍開頭的 Unix 時間戳或
strtotime
數(shù)據(jù)值。 - limit:這是每個頁面返回的單獨(dú)對象的數(shù)量。限值 0 將不返回結(jié)果。為提升性能,將為某些連線的
limit
值設(shè)置上限。在調(diào)用案例中,API 將返回正確的分頁鏈接。 - next:將返回下一頁數(shù)據(jù)的圖譜 API 端點(diǎn)。
- previous:將返回上一頁數(shù)據(jù)的圖譜 API 端點(diǎn)。
抓包發(fā)現(xiàn) 新浪微博 使用的就是 基于時間的分頁
必選 | 類型 | 描述 | |
---|---|---|---|
since_id | false | int64 | 若指定此參數(shù),則返回ID比since_id大的微博(即比since_id時間晚的微博),默認(rèn)為0。 |
max_id | false | int64 | 若指定此參數(shù),則返回ID小于或等于max_id的微博,默認(rèn)為0。 |
加載更多1:
max_id 1474446495309988
返回1:
since_id String 1474446349209988
max_id String 1474446349209988
need_insert Integer 0
num Integer 17
加載更多2:
max_id 1474446349209988
返回2:
since_id String 1474444074709993
max_id String 1474444074709993
need_insert Integer 0
num Integer 11
加載更多3:
max_id 1474444074709993
返回3:
since_id String 1474443946709988
max_id String 1474443946709988
need_insert Integer 0
num Integer 12
下拉刷新
since_id 1474446662409995
refresh pulldown
isgzip 1
preAdInterval 7
返回:
since_id String 1474447981509999
max_id String 1474447981509999
interval Integer 0
need_insert Integer 0
num Integer 0
四、延伸——數(shù)據(jù)的緩存
1、基于偏移的分頁方案 會有數(shù)據(jù)重復(fù)加載到,需要做好去重工作。
2、基于游標(biāo)的分頁方案 有數(shù)據(jù)連續(xù)性的問題。
例如 第一次 緩存 10-0 條,第二次 緩存了 30-20 條記錄。 第三次 打開 如果請求的數(shù)據(jù) 能 接上 第30條,則沒問題。但是 緩存的 10-0 條記錄 就斷掉了。
所以:
A)如果 80% 的訪問量 都是第一頁的數(shù)據(jù),例如最新的 20條 或者 40條 記錄,則可以 只緩存 第一頁的數(shù)據(jù)。
例如 新浪微博
。
B)把每次斷掉的 id 都緩存起來。等加載到的時候再連上。
C)自己想到的方案:客戶端只緩存最新的連續(xù)數(shù)據(jù)。
- 每次請求服務(wù)器的時候,都帶上最新的id(since_id)和最老的 id(max_id)。加載更多 或者 下拉刷新時,如果可以和緩存連接上,則同時返回 since_id 和 max_id 之間 變化的數(shù)據(jù)(例如刪除了某一條),客戶端做處理。
- 下拉刷新時,假如本來一頁是返回10條數(shù)據(jù),但是實(shí)際上只有11or12條數(shù)據(jù),
五、 對比
一、傳統(tǒng)分頁:
總結(jié)
傳統(tǒng)分頁的特點(diǎn):
- 可以直接根據(jù)頁碼跳轉(zhuǎn)到特定頁
- 可能會出現(xiàn)重復(fù)、丟失數(shù)據(jù)的情況
- 頁數(shù)較大時性能會降低
- 排序條件與分頁無關(guān)
游標(biāo)分頁的特點(diǎn):
- 不可以直接跳轉(zhuǎn)到特定頁(知道頁數(shù)),但是可以直接跳轉(zhuǎn)到最后一頁,能加載下一頁,上一頁。
- 不會出現(xiàn)重復(fù)、丟失數(shù)據(jù)的情況
- 查詢效率與頁數(shù)無關(guān),并且優(yōu)于傳統(tǒng)分頁
- 不適合排序條件比較復(fù)雜的分頁
參考文檔: