Mysql在數(shù)據(jù)量大的情況下,會(huì)遇到水平分表的情況。
1. 根據(jù)業(yè)務(wù)屬性拆表
這種分表方式的算法大致是取模,hash,md5等。
用業(yè)務(wù)屬性拆表,業(yè)務(wù)關(guān)系復(fù)雜的情況下,如果要根據(jù)其他條件查詢(xún),其他的條件都必須和這個(gè)屬性關(guān)聯(lián)起來(lái),查詢(xún)條件必須帶有這個(gè)屬性。
例子:
用戶(hù)profile表根據(jù)用戶(hù)ID取模進(jìn)行水平拆分。
社區(qū)里有群組,群組里有應(yīng)用,應(yīng)用有各種類(lèi)型。可以用群組ID,應(yīng)用ID拆表。
問(wèn)題:
根據(jù)某個(gè)條件查詢(xún)時(shí)無(wú)法獲取拆表的屬性
1) 條件中含有分表的信息
比如用戶(hù)在某網(wǎng)站下了訂單,我們根據(jù)用戶(hù)ID對(duì)訂單進(jìn)行了分表,這樣用戶(hù)可以方便地查詢(xún)他所關(guān)聯(lián)的訂單。但用戶(hù)投訴時(shí),客服需要根據(jù)訂單號(hào)查詢(xún)訂單,訂單號(hào)中可以含有分表的信息,比如訂單拆分成100張表,訂單號(hào)中可以有兩位用來(lái)表明該訂單處于哪張表中
2) 用key-value store存儲(chǔ)對(duì)應(yīng)關(guān)聯(lián)
原理是用key value store做索引表
3) 數(shù)據(jù)冗余
需要關(guān)聯(lián)的表可以進(jìn)行數(shù)據(jù)冗余。避免了查詢(xún)。
例子:
購(gòu)買(mǎi)禮品。購(gòu)買(mǎi)虛擬禮品時(shí),我們根據(jù)了購(gòu)買(mǎi)者的ID進(jìn)行了拆表,同時(shí)訂單號(hào)中也含有了分表信息。但是用戶(hù)還可能根據(jù)被贈(zèng)送方進(jìn)行查詢(xún),這時(shí)我們可以在購(gòu)買(mǎi)成功后為被贈(zèng)送方冗余生成一條記錄。
4) 緩存,NOSQL
和數(shù)據(jù)冗余類(lèi)似。例子中提到的群組應(yīng)用的拆表例子,我們已經(jīng)按照群組ID和應(yīng)用類(lèi)型進(jìn)行了分表。但是當(dāng)我要查詢(xún)最近所有類(lèi)型的應(yīng)用時(shí),就遇到困難了。我們需要把該群組的所有應(yīng)用類(lèi)型都查詢(xún)一遍,而且還要再進(jìn)行排序,分頁(yè)等等。其實(shí),可以用緩存的方式存儲(chǔ)最近幾百條應(yīng)用。
2. 根據(jù)時(shí)間拆表
當(dāng)表的關(guān)系比較復(fù)雜時(shí),無(wú)法根據(jù)某個(gè)維度進(jìn)行分表。但是有明顯的時(shí)效性。
例子:
想必大家都用微薄,某人發(fā)的微薄,會(huì)被推送到千家萬(wàn)戶(hù)。所以某條微薄是無(wú)法根據(jù)用戶(hù)ID進(jìn)行分表查詢(xún)。而微薄是有很強(qiáng)的時(shí)效性的。一年前的默認(rèn)的動(dòng)態(tài)信息是不會(huì)再關(guān)心的。我們把微薄按時(shí)間分表,三個(gè)月一張表。而行級(jí)緩存(memcached)只存儲(chǔ)了一個(gè)月。用戶(hù)微薄收件箱(微薄ID列表)一般都是限長(zhǎng)的。當(dāng)緩存服務(wù)器重啟或不命中時(shí),需要查詢(xún)Mysql,mysql按時(shí)間分表,緩存不命中的情況下,大部分情況下都是查近三個(gè)月的微薄。所以近1年的微薄我們可以存儲(chǔ)在物理資源比較好的數(shù)據(jù)庫(kù)服務(wù)器上。
3. 根據(jù)自增長(zhǎng)ID拆表
這種分割法不是取模分,而是每張表存指定量的數(shù)據(jù)。如果數(shù)據(jù)量到了,就存放到新表中。這樣可以完全控制每張表的數(shù)據(jù)量。關(guān)系非常簡(jiǎn)單并且有時(shí)效性的情況下可以用。
4. 數(shù)據(jù)遷移的方式
當(dāng)一些很久之前的數(shù)據(jù),很少再查詢(xún)。比如員工工資表,我們可以只存今年的工資情況。而歷史數(shù)據(jù)我們可以遷移到一張salary_old表中,保證數(shù)據(jù)不會(huì)丟失。但也可以用來(lái)查詢(xún)。
分庫(kù)的原理也類(lèi)似。