分庫分表下的分頁查詢


假設有一張用戶表,經過分庫分表之后,現在均勻分布在2台服務器。每個服務器2張表

   1. 全局視野法:因為不清楚按照時間排序之后的第三頁數據到底是如何分布在數據庫上的,所以必須每個庫都返回3頁數據,所得到的6頁數據在服務層進行內存排序,得到全局視野,再取第3頁數據。

     優點:通過服務層修改,擴大數據查詢量,得到全局視野,業務無損,精確

     缺點(顯而易見):每個分庫都需要返回更多的數據,增大網絡傳輸量;除了數據庫要按照time排序,服務層也需要二次排序,損耗性能;隨着頁碼的增大,性能極具下降,數據量和排序量都將大增,性能平方級下降。

    2. 業務折中

     2.1 禁止跳頁查詢,不提供“直接跳到指定頁面”的功能,只提供下一頁的功能。極大的降低技術方案的復雜度。第一頁的選取方法和全局視野法一樣,但是點擊下一頁時:

       2.1.1先找到上一頁的time的最大值,作為第二頁數據拉去的查詢條件,只取每頁的記錄數,

       2.2.2這樣服務層還是獲得兩頁數據,再做一次排序,獲取一頁數據。

       2.2.3改進了不會因為頁碼增大而導致數據的傳輸量和排序量增大

    3. 允許數據精度丟失:需要考慮業務員上是否接受在頁碼較大是返回的數據不是精准的數據。

     3.1在數據量較大,且ID映射分布足夠隨機的話,應該是滿足等概率分布的情況的,所以取一頁數據,我們在每個數據庫中取前半頁。

     3.2當然這樣的到的結果並不是精准的,但是當實際業務可以接受的話, 此時的技術方案的復雜度變大大降低。也不需要服務層內存排序了。

    4. 二次查詢法:既滿足業務的精確需求,也無需業務折中。現在假設每頁顯示10條數據,要查第三頁,數據分了兩個庫。 正常的語句是 select * from table order by time offset 20 limit 10,取偏移20個之后的10個

     4.1首次查詢查詢每個庫的select * from table order by time offset 10 limit 10;得到10條數據。這里的offset是總offset/分庫數

     4.2 服務層得到來自兩個分庫的結果集,得到最小的time,也就是最頂層的time,這個time滿足最少有10條記錄在它前面,然后分別記錄每個庫的最大time

     4.3 分別再次查詢最小time->每個庫上一次的最大time的數據,得到每個庫的查詢結果

     4.4 在每個集合的最小time都是相同的,所以可以得到該最小time在整個數據庫中的offset,加起來就是這個最小time在全局庫的offset位置。

     4.5 再將第二次查詢的結果集拼起來和得到的最小time的offset,推導出 offset 20 limit 10的一頁記錄。

     優點:可以精確得到業務數據,且每次返回的數據量都非常小,不會隨着頁碼增加而數據量增大。

     缺點:需要進行兩次數據庫查詢

   5.通過額外的添加一張關聯表,屬性中必有id屬性,至於是否有庫id屬性和表id屬性(既第幾個庫和第幾個表)可有可無,因為這個可以根據id自行取模獲取,注意這張表存放的數據是所有數據,但是勝在屬性列少,只有提供索引的幾個屬性列,這樣的話我們只需要select * from brand_temp where … limit 400,10(插敘第41頁的數據,每頁顯示5條數據),然后我們獲取了id之后就可以去對應的表中查詢了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM