當(dāng)業(yè)務(wù)上按照月份分表,但是前端h5需要分頁展示,小伙伴們不知有沒有遇到這個(gè)這個(gè)需求最后怎么完成的。
成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)與策劃設(shè)計(jì),長汀網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:長汀等地區(qū)。長汀做網(wǎng)站價(jià)格咨詢:18982081108
我這里想了一個(gè)解決思路,可能還不完善,希望能拋轉(zhuǎn)引玉。
1、入?yún)ageNo 為頁號(hào)碼,如果為1那么就是第一頁。pageSize 可以是入?yún)⒁部啥ㄋ?,這里定死10條。Limit 是數(shù)據(jù)偏移標(biāo)記,根據(jù)入?yún)ageNo 計(jì)算出來的,Limit=(pageNo-1)*pageSize。假設(shè)A表有41條數(shù)據(jù)符合,B表有51條數(shù)據(jù)符合,如下圖。
有幾種種情況? ?1.如果limitA表41條 那么需要從A表中取數(shù)據(jù),(1)如果Limit+pageSizeCount直接獲取數(shù)據(jù)即可(2)如果Limit+pageSizeCount,那么需要從A 表取部分?jǐn)?shù)據(jù)從B表取一部分?jǐn)?shù)據(jù)。
1.如果limitA表41條? 那么需要從B表取數(shù)據(jù),如果B數(shù)據(jù)依然不足,那么重復(fù)以上的步驟。如下圖
一個(gè)不帶limit 一個(gè)帶limit。以php+mysql為例首先,連接數(shù)據(jù)庫,寫一條sql語句把你要查詢的信息總量查找出來sql = select count(*) from tb,$all_page ;設(shè)定每頁顯示條數(shù), $display 。然后,當(dāng)前頁為$page ;在寫一句sql = select * from tb limit $dispaly*($page - 1),$display;最后,在頁面顯示分頁信息把當(dāng)前頁傳回給分頁處理頁,一定要把相關(guān)的條件一起傳回去,get 方式傳值,否則查詢條件改變查詢信息就不正確。 網(wǎng)上有好多封裝好的分頁類。我也有一個(gè)很好用的分頁類,如果請(qǐng)我吃肉就發(fā)給你一份哈。。\(^o^)/~ 追問: 這個(gè)$all_page用在哪兒,怎么將當(dāng)前頁傳回給分頁處理頁。顯示的時(shí)候那些“首頁”“上一頁”“下一頁”“末頁”是鏈接嗎、鏈到什么地方,還是別的什么 回答: $all_page是查詢總數(shù),總是頁數(shù)等于查詢總數(shù)除以每頁顯示的信息。$num_page = ceil($all_page/$display); 用get方式把當(dāng)前頁傳給分頁處理頁,就是a href = "連接到本頁或著不寫也就是當(dāng)前頁?page=當(dāng)前頁碼"/a標(biāo)簽 別的我也想不起來,讓我自己寫分頁,我只會(huì)最簡(jiǎn)單的那種,一般我都是調(diào)用一個(gè)現(xiàn)成的分頁類。只需傳個(gè)參數(shù)就Ok,連樣式都不用寫的。。。
直接用limit start, count分頁語句, 也是我程序中用的方法:
select * from product limit start, count
當(dāng)起始頁較小時(shí),查詢沒有性能問題,我們分別看下從10, 100, 1000, 10000開始分頁的執(zhí)行時(shí)間(每頁取20條), 如下:
select * from product limit 10, 20 0.016秒
select * from product limit 100, 20 0.016秒
select * from product limit 1000, 20 0.047秒
select * from product limit 10000, 20 0.094秒
我們已經(jīng)看出隨著起始記錄的增加,時(shí)間也隨著增大, 這說明分頁語句limit跟起始頁碼是有很大關(guān)系的,那么我們把起始記錄改為40w看下(也就是記錄的一般左右) select * from product limit 400000, 20 3.229秒
再看我們?nèi)∽詈笠豁撚涗浀臅r(shí)間
select * from product limit 866613, 20 37.44秒
難怪搜索引擎抓取我們頁面的時(shí)候經(jīng)常會(huì)報(bào)超時(shí),像這種分頁最大的頁碼頁顯然這種時(shí)
間是無法忍受的。
從中我們也能總結(jié)出兩件事情:
1)limit語句的查詢時(shí)間與起始記錄的位置成正比
2)mysql的limit語句是很方便,但是對(duì)記錄很多的表并不適合直接使用。
如果要獲取第N頁的數(shù)據(jù)(每頁S條數(shù)據(jù)),則將每一個(gè)子庫的前N頁( offset 0,limit N*S )的所有數(shù)據(jù)都先查出來(有篩選條件或排序規(guī)則的話都包含),然后將各個(gè)子庫的結(jié)果合并起來之后,再做查詢下 top S (可不用帶上相同的篩選條件,但還要帶上排序規(guī)則)即可得出最終結(jié)果,這種方式類似es分頁的邏輯。
如果要獲取第N頁的數(shù)據(jù),第一頁時(shí),是和全局視野法一致,但第二頁開始后,需要在每一個(gè)子庫查詢時(shí),加上可以排除上一頁的過濾條件(如按時(shí)間排序時(shí),獲取上一頁的最大時(shí)間后,需要加上 time ${maxTime_lastPage} 的條件;如果沒有排序規(guī)則,由于是默認(rèn)主鍵id的排序規(guī)則,也可加上 id ${maxId_lastPage} 的條件),然后再 limit S ,即可獲取各個(gè)子庫的結(jié)果,之后再合并后 top S 即可得到最終結(jié)果。在類似app中列表下拉的場(chǎng)景中,業(yè)務(wù)上可以禁止跳頁查詢,此時(shí)可以使用這種方式。
在大數(shù)據(jù)量的前提下,需要查詢的數(shù)據(jù),從概率論角度,是均勻分布在各個(gè)字庫中的,因此可以假定需要查詢的第N頁數(shù)據(jù),在子庫中都處于第 N/X 頁的前 S/X 條中(X=子庫數(shù));所以查詢子庫時(shí),限定 offset ((N/X)-1)*S/X,limit S/X 即可,例 N=S=100,X=2 時(shí),子庫分頁條件為 offset 4950,limit 50 ;然后合并子庫結(jié)果后即可得出最終結(jié)果,當(dāng)然這個(gè)結(jié)果是不準(zhǔn)確的。在類似網(wǎng)頁回帖上的場(chǎng)景下,往往數(shù)據(jù)精度要求不太高,此時(shí)可以使用這種方式。
也是在大數(shù)據(jù)量的前提下,依據(jù)概率論,可以假定需要查詢的第N頁的數(shù)據(jù),在子庫中都處于第 N/X 頁的后面。然后可按如下步驟查詢:
1). [第一次查詢] 按指定條件(篩選條件或排序規(guī)則條件)查詢各個(gè)子庫的S條數(shù)據(jù),即 offset ((N/X)-1)*S/X,limit S
2). 如果沒有排序規(guī)則條件,則默認(rèn)主鍵id排序,那么獲取各個(gè)子庫的返回?cái)?shù)據(jù)的最小值和最大值: min_i_id,max_i_id ;如果有排序條件,就按排序條件獲取
3). 比較各個(gè)子庫的 min_i_id ,得到最小的,定義為 min_id
4). [第二次查詢] 再次查詢(有篩選條件的話也要包含)各個(gè)子庫,加上條件: min_ididmax_i_id ;(注: min_i_id = min_id 的子庫可省略查詢)
5). 查看第二次查詢結(jié)果中, min_id_id != min_id 的其它子庫中,共多了幾條數(shù)據(jù),如果多了M條,則可以得出全局中,min_id前面的數(shù)據(jù)有 (((N/X)-1)*S/X)*X - M = ((N/X)-1)*S-M 條, ((N/X)-1)*S-M 即為 min_id 的全局offset
6). 計(jì)算真正的全局offset: ((N-1)*S) 和 min_id 的全局offset: ((N/X)-1)*S-M 之間的差值K,由公式可得: K=0
7). 合并第二次查詢的各子庫結(jié)果,并按id排序后,以 K為offset,S為limit 即可得到最終全局的分頁結(jié)果
參考:
你可以先count一下各分表,再根據(jù)頁數(shù)來取數(shù)據(jù)
或都使用中間件進(jìn)行取數(shù)據(jù)