溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

mysql分庫后如何查詢

發(fā)布時間:2020-09-23 13:06:14 來源:億速云 閱讀:213 作者:小新 欄目:MySQL數(shù)據(jù)庫

小編給大家分享一下mysql分庫后如何查詢,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

分庫分表的策略,依項目需求而定,這里采用的是常規(guī)的做法:根據(jù)取模的方式,假設我們水平分庫2個,每個庫又水平拆表2個 既總共有4個表,查詢的時候默認沒有按照其他的條件進行排序,假設我們要查詢第41頁的數(shù)據(jù),每頁顯示10條數(shù)據(jù)

第一種:

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

第二種:

最耗費性能的一種,如果我們要查詢第一頁的記錄,單庫單表的sql為:select * from db limit 0,10; 當我們分庫分片之后 語句還是同樣的語句,但是這時候我們需要對4個表返回的記錄在內(nèi)存中進行解析,然后通過id進行升序,取得前10條數(shù)據(jù)返回…數(shù)據(jù)量小,頁碼小的時候很ok,但是如果我們要查詢第2頁的數(shù)據(jù)的時候,sql單體架構的情況下為:select * from db limit 10,10; 但是在分布式數(shù)據(jù)庫這樣是不行的,數(shù)據(jù)很明顯會丟失,彌補的方法是查詢所有,sql語句為select * from db_x limit 0,10+10 //意味著需要查詢的是本在單體架構上要查詢的記錄數(shù)加上之前的記錄 ,然后再在內(nèi)存中合并所有表返回的記錄然后進行解析,最后取第10開始的記錄 …可以看出這個方案一旦頁碼數(shù)達到n頁,而每頁顯示的記錄數(shù)為m條記錄的時候,每個表需要查詢的記錄數(shù)為:(n-1)*m+m=nm條記錄,內(nèi)存中需要解析的記錄數(shù)為 t * n * m 條記錄,cpu不爆炸算我輸

第三種:

采取的是基于業(yè)務的模式:迫使用戶無法進行跳頁查詢,什么意思呢,就是用戶只能點擊下一頁或者上一頁的方式瀏覽,具體的做法在于查詢得到記錄數(shù)的同時記錄下當前唯一id值的最大值,然后再次查詢的時候添加where 條件…讓我們從頭開始捋: 第一次查詢pageNum=1,pageSize=10 ,maxId=0->sql:select * from db_x where id>0 limit 10; 然后分發(fā)到對應的庫的表中,將得到的4*10條數(shù)據(jù)合并,再在內(nèi)存中進行解析排序,取前10條數(shù)據(jù),同時將第10條數(shù)據(jù)的id=maxId單獨取出渲染到前端頁面上保存,這樣當點擊下一頁的時候,這個maxId=10也提交上去了,sql 變成了select * from db_x where id>10 limit 10,然后繼續(xù)解析,繼續(xù)保存…這種方式返回的數(shù)據(jù)都是穩(wěn)定的并且數(shù)據(jù)是連貫的(排序)

第四種:

傳說中的最好的方式,支持跳頁查詢,這個方式核心在于2次sql查詢,具體怎么做呢:

前提條件假設:查詢第1001頁的數(shù)據(jù),每頁顯示10條記錄

1):我們先記錄下要查詢的記錄數(shù)的范圍:(1001-1)*10=10000 開始,10010結束->10000-10010
單體的sql為:select * from db limit 10000,10;
我們總共有4個表,意味著:每個表的start應該為10000/4=2500,從而sql變成了:
select * from db_x limit 2500,10;	//假設是平均分配的,因而我們可以均分,不均分也沒關系,后續(xù)操作會補齊
我們會得到4個表中的記錄:(因為我demo還沒寫,所以先手寫了)
T1:(1,"a"),.......
T2:(2,"b"),.......
T3:(3,"c"),.......
T4:(4,"d"),.......
真實數(shù)據(jù)第1001頁不可能是1開頭的,將就著看吧,過幾天會一起講rabbitMQ分布式一致性和這個demo一起發(fā)布的
ok,第一階段的sql查詢結束

2):對4個表中返回的記錄進行id匹配(id如果非整型,自行用hashCode匹配),因為是升序查詢,所以我們只需要比較下每個表的首條記錄
的id值即可,獲得了最小的minId=1,和各個表最大的那個值maxId;ok,轉(zhuǎn)換sql思路,這里我們采用條件查詢了(彌補操作第一步):
select * from db_x where id between minId and maxId 這樣我們就獲取到了遺漏的數(shù)據(jù)(當然有多余的數(shù)據(jù))
這樣我們4個表中就返回了可能記錄數(shù)各不相同的記錄,第二步結束

3):
之后記錄minId出現(xiàn)的位置,如T1出現(xiàn)的位置為2500,T2出現(xiàn)的位置為2500-2=2048 ,T3出現(xiàn)的位置為2500-3=2047 ,T4出現(xiàn)的位置
為2500-3=2047 則最終出現(xiàn)的記錄數(shù)為:2500+2048+2047+2047=10000-2-3-3=9992,因此我們需要的查詢的記錄數(shù)需要從9992 依次往后取
8個開始,然后再取10個就是所求的數(shù)據(jù),這種方式能做到數(shù)據(jù)精確查詢,但是唯一的缺點就是每次查詢都需要進行二次sql查詢

看完了這篇文章,相信你對mysql分庫后如何查詢有了一定的了解,想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI