一、背景:
系統剛開始的時候,資料庫都是單庫單錶結構。隨著業務量的增加進行第一次資料庫公升級,根據業務垂直拆分資料庫,這樣多變成多個業務資料庫,每個資料庫裡面還是單錶結構。接下來,繼續隨著業務量的繼續增加,單錶已經很難承受資料量,就要進行分表,這個時候就是,多個業務庫,每個業務庫下對需要分表的表進行分表。再接下來,隨著應用的增加,資料庫io,磁碟等等都抗不住了,就要把分表的表分到多個庫,這樣就形成了如下的結構。
重點:本文主要討論的是分庫分表的策略,也就是分庫分表的規則或者說是演算法。
二、分庫分表的依據--分庫分表字段的選擇
分庫分表首先要確定根據哪個字段、或者哪幾個字段進行路由,一般的原則是按使用頻率最高維度的字段去分庫分表,盡量保證高使用維度下只查詢單錶。
常用的字段有主鍵id,使用者id,時間,商戶id,產品id,業務型別等等
三、分庫分表策略
主要原理:分割槽、取模、資料路由表
1. 按照時間區間
1)基本原理:
一定區間內時間產生的資料放到一張表裡面,多個時間區間的表放到乙個庫裡面
2)簡單例子:
單庫多表結構,按月分表可以這樣,user_201601,user_201602,...,user_201612這種結構。按年分表可以這樣,user_2016,user_2017,...這種。
3)多庫多表演算法:
比如按天分表,每天一張表,當單庫超過100張表的時候,進行分庫到下一張表。那麼假如第一張報表在庫bd0,表名是user_20160201。從db0.user_20160201,..到db0.user_20160511就100張表了,接下來就要進行分庫了,進入20160512,就是db1.user_20160512,這個演算法就是上線的時候定乙個上線日期,具體演算法如下
庫id = (當前日期 - 上線日期)/ 100
表id = user_yyyymmdd
注:好處是可以直接根據時間經過簡單計算定位到哪個庫和哪個表
還有一種演算法:
庫id = (當前日期 - 上線日期)/ 100
表id = (當前日期 - 上線日期) % 100
表名如下: db0.user_0001, user_0002,....,user_01000。
注:表名和庫名都要經過計算,比較麻煩
4)按月分表,每個月一張表;這種情況,一般就不用分庫了,一年12張表說明量也不會特別大,如果量特別大,或者是熱點資料,可以一年分乙個庫,具體演算法和上面差不多。
5)按季度分表,基本不用分庫。
6)按年分表,肯定不用分庫了,沒有必要了。
2. 按照主鍵id區間
對於自增的主鍵id,可以按照id區間進行分表,以1000萬資料量為分界線,對線性的id進行切割分表,每漲到1000萬資料,分到下一張表,超過一定數目的表,進行分庫。
庫id = 主鍵id / 1000萬 / 100
表id = 主鍵id / 1000萬 % 100
如:db0.user_0000,...,db0.user_0099, db1.user_0000,...,db1.user_0099
3. 按照指定欄位hash後再取模
如果要取模的字段不是整數型,要先hash後,再通過取模演算法,算出在哪個庫和那個表。具體演算法,參照下面的按使用者id取模。
4. 按照使用者id取模
這裡把按照使用者id取模單獨拎出來,因為就使用而言,是使用場景最多的情況,很多時候都是使用者相關資料量最大,需要分庫分表,查詢維度更多也是按照使用者來查詢,所以對使用者取模,讓同乙個使用者的資料落到一張表裡面,再好不過了。
案例:假設使用者id是整數型的。庫數量要分4庫,每個庫表數量8表,一共32張表。
原理講解:
一共要分4庫,8表,共32張表,也就是1到32的使用者id要平均分配到每張表應該有一條資料,這樣就有兩種分法。
1) 1到8是第乙個庫,9到16第二個庫,17到24第三個庫,25到32是第四個庫,每個庫裡面表的編號都是0到3,這個原則是乙個庫裡面乙個乙個分,分完再下乙個庫乙個乙個分,保證不重複,不漏掉。
2)1,5,9這樣每隔4個乙個庫,2開頭隔4個乙個庫,這個原則是乙個庫分乙個,在分下乙個庫,一圈走完,再在第一庫沒分到的表繼續分,也保證了不重複,不漏掉原則。
庫id = userid % 庫數量4
表id = userid / 庫數量4 % 表數量8
或者 庫id = userid / 表數量4 % 庫數量4
表id = userid % 表數量8
演算法圖示如下:
5. 資料路由表
如果分庫分表的演算法很複雜,可以通過路由表+程式演算法,來儲存和計算分庫分表規則,不過一般不建議,分庫分表搞得太複雜,不便於維護和查詢問題
四、各個方案對比
分割槽演算法
優點:線性擴容,平滑擴容,不需要資料遷移
缺點:存在熱點資料,非時間維度查詢多的情況,聚合複雜
建議:冷資料,使用者維度查詢少,且資料量大的情況用分割槽演算法
取模演算法
優點:同乙個熱點的資料可以做到乙個表裡面,查詢方便
缺點:擴容不是很方便,需要資料遷移
建議:使用者維度查詢多,熱點維度查詢多的情況,建議使用
注:
分庫分表的核心是未來資料量的預估,根據預估和實際使用情況來確定分庫分表方案,一般像訂單類資料以使用者維度取模分表最好,商品資料以商戶取模最好,簽到等活動流水資料時間分割槽最好。
取模方案擴容的解決:一、可以提前按照預估方案建立庫和表,前期放到乙個db,後期遷移,或者一次性弄好 二、可以按照預估的方案去確定分庫和分表的字尾id,但是前期只建立一部分庫和表。例如:最終4庫,每個庫16個表。字尾應該是0000----0315共64個表的字尾,前期可以乙個庫,4個表,也就是所有資料都在這個四張表裡面。
0000--0003-----》0000表
0100--0103-----》0000表
0200--0203-----》0000表
0300--0303-----》0000表
0004--0007-----》0004表
0104--0107-----》0004表
0204--0207-----》0004表
0304--0307-----》0004表
0008--0011-----》0008表
0108--0111-----》0008表
0208--0211-----》0008表
0308--0311-----》0008表
0012--0015-----》0012表
0112--0115-----》0012表
0212--0215-----》0012表
0312--0315-----》0012表
後續可以二分法,遷移資料,擴容。
資料庫 分庫分表以及切分策略
隨著業務和資料量的增長,單庫的io壓力越來遠大,可將單一資料庫的資料分散到多個資料庫中,來緩解資料庫的訪問壓力。資料庫切分的兩種方式 垂直分庫 根據業務的耦合程度,將關聯度低的表儲存在不同的資料庫中。與微服務的做法相似,每個微服務使用單獨的資料庫。垂直分表 基於資料庫中的列進行。新建一張擴充套件表,...
資料庫分庫分表
1 基本思想之什麼是分庫分表?從字面上簡單理解,就是把原本儲存於乙個庫的資料分塊儲存到多個庫上,把原本儲存於乙個表的資料分塊儲存到多個表上。2 基本思想之為什麼要分庫分表?資料庫中的資料量不一定是可控的,在未進行分庫分表的情況下,隨著時間和業務的發展,庫中的表會越來越多,表中的資料量也會越來越大,相...
資料庫分庫 分表
分庫的優點是 實現簡單,庫與庫之間界限分明,便於維護,缺點是不利於頻繁跨庫操作,單錶資料量大的問題解決不了。分表的優點是 能解決分庫的不足點,但是缺點卻恰恰是分庫的優點,分表實現起來比較複雜,特別是分表規則的劃分,程式的編寫,以及後期的 資料庫拆分移植維護。實際應用中,一般網際網路企業的路線都是先分...