mysql分庫分表后,跨庫跨表搜索如何排序?
mysql分為數據庫和表后,跨數據庫和跨表搜索如何排序?在單個表中處理大量數據是一種非常常見的。比如我們的訂單表,一般情況下,我們會按照一個月、三個月、六個月以上的維度來劃分運單表,自然也會按照時間來橫向劃分訂單表。
在這種情況下,子倉庫和子表非常容易處理,因為我們可以根據時間軸強制將訂單存儲在不同的倉庫中。但是,有可能我們的電商系統用戶量大,訂單量大。一天有幾十萬單。可能短短半個月,我們的訂單量就上千萬了。加上訂單的商品數據表,如果沒有表,訂單表可能會拖累系統。
那么我們必須面對的是,一個月內的數據要按照一定的規則劃分到不同的數據庫和表格中。我們可以把訂單表分成兩部分,OrderDB1和OrderDB2,根據我們的訂單號來區分。如果訂單號是單數,我們就放在OrderDB1,如果訂單號是偶數,我們就放在OrderDB2。這樣訂單表的數據均勻分布到兩個數據庫的表中,減少了單個表的壓力。
在此之后,我們的訂單表將很難按頁面排序。兩個數據庫中的數據如何跨數據庫按頁排序?
一般我們有三種方法,即全局視覺模式、容許精度損失模式和二次搜索模式。
讓讓我們先談談全局視圖模式。通常我們要在第三頁找到100個訂單的數據,我們會寫一個SQL。
select*fromtorderbytimeoffset200limit100。但是這100條數據分庫后可能會有很多辦法。
它可能是均勻分布的(在極端情況下)
也有可能都來自一個庫(極端情況下)。
它也可能是分散的(通常)
因為按照我們的OrderBy條件有很多可能,所以我們很難知道第三頁的數據是從哪個庫的哪里開始取的。如果我們需要準確地獲得數據,那么我們必須恢復單個庫的全局視野。
如何恢復全球視野?
讓讓我們以第三頁上我們要查詢的數據為例。我們失去全球視野的原因是我們可以我們不可能一下子得到所有的數據結果,所以恢復我們全球視野的方法就是讓我們得到所有的數據結果。所以我們可以在兩個庫中查詢第一頁到第三頁的所有數據,然后在內存中合并排序,然后從第三頁就可以得到正確的數據。
自然地,我們的sql也發生了變化,從
通過時間偏移200li從T訂單中選擇*麻省理工100改成了
select*fromtorderbytimeoffset0limit100200使用全局視圖模式的好處很明顯,就是數據絕對準確。但是,缺點也很明顯。當查詢數據較大時,內存消耗會增加,當頁數增加時,查詢效率會迅速下降。當我們有N個數據庫時,我們需要查詢從X到XY的數據,那么我們需要在內存中組合N*(XY)條數據,并對它們進行排序。
既然全局查詢方法有缺點,我們會解決這個缺點,但是肯定會有一些其他的犧牲。
允許精度損失的方法其實很好理解,就是Idon我不關心數據在兩個數據庫中是如何分布的。我只是從兩個數據庫中平均整理出50條數據,然后組合成100條進行展示。
當然,這種方法的準確性會根據你的排序條件和數據存儲而有所不同。假設我們的數據是按時間順序存儲的,我們的排序也是基于時間的,那么我們得到的結果會更準確。
然而,如果我們的數據被隨機插入多個數據庫s,我們要按時間排序和搜索,或者我們的數據是按時間順序插入DB的,但是當我們需要按其他條件搜索時,數據的準確性就會很差。這取決于我們的業務需求是什么。
然而,用這種方法搜索,我們不不必考慮性能問題,并且查詢的復雜性非常低。只要我們的業務沒有太多的要求,那么使用這種方法是最推薦的。
當然,如果你的業務不允許這種情況發生,你還需要滿足交互、效率等各種需求,那么我們也可以使用下面的方法。
第二種查詢模式可以說是解決子庫查詢的終極武器,可以保證數據的準確性、查詢的效率和用戶的交互頁面,代價只是很小的性能開銷和一定的代碼難度。
其實方法并不難。假設我們想查詢第21頁的數據,每頁5篇文章。在這個時候,讓假設數據是均勻分布的,但是我們查詢每個庫中的全部5條數據。那就是:
select*fromTorderbytimeoffset100限制5
這個時候我們得到的數據可能是這樣的。
兩個db中,時間最短的是1487500001【minTime】,記錄了這個時間。還記錄了兩個db中的最大時間,即db1:1487500041[maxtime1]和DB2:1487500061[maxtime2]。
這時候我們在使用時間內再去兩個數據庫查詢。
挑選*fromtwheretimebetweenminTimeandmaxtime1orderbytimeselect*fromtwheretimebetweenminTimeandmaxtime2orderbytime由于之前minTime來自DB1,所以DB1的數據不會改變,但是DB2中的條件放寬了,所以可能會查詢到更多的數據。結果可能如下:
兩個結果合并后,相當于得到了一個全局視圖,很容易就能找出這個頁面需要的五條數據。
當然我們也可以使用elasticsearch來完成子數據庫的排序搜索,因為elasticsearch引入了緩存機制,可以讓查詢更快。
mysql數據庫分庫分表后要是有跨表的查詢怎么處理,分頁的時候怎么處理?
可以先統計子表,再根據頁數獲取數據,或者使用中間件獲取數據。mysql數據庫分表后,如何處理跨表查詢,分頁時如何處理。