分表分库时机选择及策略
轉(zhuǎn)載自? ?分表分庫時(shí)機(jī)選擇及策略
一. 分表
應(yīng)用場(chǎng)景:
對(duì)于大型的互聯(lián)網(wǎng)應(yīng)用來說,數(shù)據(jù)庫單表的記錄行數(shù)可能達(dá)到千萬級(jí)甚至是億級(jí),并且數(shù)據(jù)庫面臨著極高的并發(fā)訪問。采用Master-Slave復(fù)制模式的MySQL架構(gòu),只能夠?qū)?shù)據(jù)庫的讀進(jìn)行擴(kuò)展,而對(duì)數(shù)據(jù)庫的寫入操作還是集中在Master上,并且單個(gè)Master掛載的Slave也不可能無限制多,Slave的數(shù)量受到Master能力和負(fù)載的限制。
因此,需要對(duì)數(shù)據(jù)庫的吞吐能力進(jìn)行進(jìn)一步的擴(kuò)展,以滿足高并發(fā)訪問與海量數(shù)據(jù)存儲(chǔ)的需要!
設(shè)計(jì)策略
? ? ??對(duì)于訪問極為頻繁且數(shù)據(jù)量巨大的單表來說,我們首先要做的就是減少單表的記錄條數(shù),以便減少數(shù)據(jù)查詢所需要的時(shí)間,提高數(shù)據(jù)庫的吞吐,這就是所謂的分表!
? ? ? 在分表之前,首先需要選擇適當(dāng)?shù)姆直聿呗?#xff0c;使得數(shù)據(jù)能夠較為均衡地分不到多張表中,并且不影響正常的查詢!
? ? ? 對(duì)于互聯(lián)網(wǎng)企業(yè)來說,大部分?jǐn)?shù)據(jù)都是與用戶關(guān)聯(lián)的,因此,用戶id是最常用的分表字段。因?yàn)榇蟛糠植樵兌夹枰獛嫌脩鬷d,這樣既不影響查詢,又能夠使數(shù)據(jù)較為均衡地分布到各個(gè)表中(當(dāng)然,有的場(chǎng)景也可能會(huì)出現(xiàn)冷熱數(shù)據(jù)分布不均衡的情況),如下圖:
?
假設(shè)有一張表記錄用戶購買信息的訂單表order,由于order表記錄條數(shù)太多,將被拆分成256張表。
拆分的記錄根據(jù)user_id%256取得對(duì)應(yīng)的表進(jìn)行存儲(chǔ),前臺(tái)應(yīng)用則根據(jù)對(duì)應(yīng)的user_id%256,找到對(duì)應(yīng)訂單存儲(chǔ)的表進(jìn)行訪問。
這樣一來,user_id便成為一個(gè)必需的查詢條件,否則將會(huì)由于無法定位數(shù)據(jù)存儲(chǔ)的表而無法對(duì)數(shù)據(jù)進(jìn)行訪問。
注:拆分后表的數(shù)量一般為2的n次方,就是上面拆分成256張表的由來!
假設(shè)order表結(jié)構(gòu)如下:
?create?table?order_(order_id?bigint(20)?primary?key?auto_increment,user_id?bigint(20),user_nick?varchar(50),auction_id?bigint(20),auction_title?bigint(20),price?bigint(20),auction_cat?varchar(200),seller_id?bigint(20),seller_nick?varchar(50) )那么分表以后,假設(shè)user_id = 257,并且auction_id = 100,需要根據(jù)auction_id來查詢對(duì)應(yīng)的訂單信息,則對(duì)應(yīng)的SQL語句如下:
select?*?from?order_1?where?user_id=257?and?auction_id?=?100;其中,order_1是根據(jù)257%256計(jì)算得出,表示分表之后的第一張order表。
?
二. 分庫
?應(yīng)用場(chǎng)景:
分表能夠解決單表數(shù)據(jù)量過大帶來的查詢效率下降的問題,但是,卻無法給數(shù)據(jù)庫的并發(fā)處理能力帶來質(zhì)的提升。面對(duì)高并發(fā)的讀寫訪問,當(dāng)數(shù)據(jù)庫master服務(wù)器無法承載寫操作壓力時(shí),不管如何擴(kuò)展slave服務(wù)器,此時(shí)都沒有意義了。因此,我們必須換一種思路,對(duì)數(shù)據(jù)庫進(jìn)行拆分,從而提高數(shù)據(jù)庫寫入能力,這就是所謂的分庫!
?
設(shè)計(jì)策略
與分表策略相似,分庫可以采用通過一個(gè)關(guān)鍵字取模的方式,來對(duì)數(shù)據(jù)訪問進(jìn)行路由,如下圖所示:
?
? ? 還是之前的訂單表,假設(shè)user_id 字段的值為258,將原有的單庫分為256個(gè)庫,那么應(yīng)用程序?qū)?shù)據(jù)庫的訪問請(qǐng)求將被路由到第二個(gè)庫(258%256 = 2)。
?
三. 分庫分表
應(yīng)用場(chǎng)景:
有時(shí)數(shù)據(jù)庫可能既面臨著高并發(fā)訪問的壓力,又需要面對(duì)海量數(shù)據(jù)的存儲(chǔ)問題,這時(shí)需要對(duì)數(shù)據(jù)庫既采用分表策略,又采用分庫策略,以便同時(shí)擴(kuò)展系統(tǒng)的并發(fā)處理能力,以及提升單表的查詢性能,這就是所謂的分庫分表。
設(shè)計(jì)策略
分庫分表的策略比前面的僅分庫或者僅分表的策略要更為復(fù)雜,一種分庫分表的路由策略如下:
??? 1. 中間變量 = user_id % (分庫數(shù)量 * 每個(gè)庫的表數(shù)量)
? ? 2. 庫 = 取整數(shù) (中間變量 / 每個(gè)庫的表數(shù)量)
? ? 3. 表 = 中間變量 % 每個(gè)庫的表數(shù)量
同樣采用user_id作為路由字段,首先使用user_id 對(duì)庫數(shù)量*每個(gè)庫表的數(shù)量取模,得到一個(gè)中間變量;然后使用中間變量除以每個(gè)庫表的數(shù)量,取整,便得到對(duì)應(yīng)的庫;而中間變量對(duì)每個(gè)庫表的數(shù)量取模,即得到對(duì)應(yīng)的表。
分庫分表策略詳細(xì)過程如下:
假設(shè)將原來的單庫單表order拆分成256個(gè)庫,每個(gè)庫包含1024個(gè)表,那么按照前面所提到的路由策略,對(duì)于user_id=262145 的訪問,路由的計(jì)算過程如下:
1. ?中間變量 = 262145 % (256 * 1024) = 1
2. ?庫 = 取整 (1/1024) = 0
3. ?表 = 1 % 1024 = 1
這就意味著,對(duì)于user_id=262145 的訂單記錄的查詢和修改,將被路由到第0個(gè)庫的第1個(gè)order_1表中執(zhí)行!!!
總結(jié)
以上是生活随笔為你收集整理的分表分库时机选择及策略的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: obs直播电脑配置要求(obs直播电脑配
- 下一篇: 为什么选择微服务架构?如何取舍?