溫馨提示×

溫馨提示×

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

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

MySQL分庫分表的使用方法

發(fā)布時(shí)間:2020-06-02 17:56:23 來源:網(wǎng)絡(luò) 閱讀:381 作者:三月 欄目:MySQL數(shù)據(jù)庫

下文給大家?guī)碛嘘P(guān)MySQL分庫分表的使用方法內(nèi)容,相信大家一定看過類似的文章。我們給大家?guī)淼挠泻尾煌??一起來看看正文部分吧,相信看完MySQL分庫分表的使用方法你一定會(huì)有所收獲。

MySQL使用分庫分表

1 什么是分庫分表?
把原本存儲(chǔ)于一個(gè)庫的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)庫上,把原本存儲(chǔ)于一個(gè)表的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)表上。
2 為什么要分庫分表?

數(shù)據(jù)庫中的數(shù)據(jù)量不一定是可控的,在未進(jìn)行分庫分表的情況下,隨著時(shí)間和業(yè)務(wù)的發(fā)展,庫中的表會(huì)越來越多,表中的數(shù)據(jù)量也會(huì)越來越大,相應(yīng)地,數(shù)據(jù)操作,增刪改查的開銷也會(huì)越來越大;另外,由于無法進(jìn)行分布式式部署,而一臺(tái)云服務(wù)器的資源(CPU、磁盤、內(nèi)存、IO等)是有限的,最終數(shù)據(jù)庫所能承載的數(shù)據(jù)量、數(shù)據(jù)處理能力都將遭遇瓶頸。
3 分庫分表的實(shí)施策略。
MySQL分庫分表的使用方法

分庫分表有垂直切分和水平切分兩種。
3.1 何謂垂直切分,即將表按照功能模塊、關(guān)系密切程度劃分出來,部署到不同的庫上。例如,我們會(huì)建立定義數(shù)據(jù)庫workDB、商品數(shù)據(jù)庫payDB、用戶數(shù)據(jù)庫userDB、日志數(shù)據(jù)庫logDB等,分別用于存儲(chǔ)項(xiàng)目數(shù)據(jù)定義表、商品定義表、用戶數(shù)據(jù)表、日志數(shù)據(jù)表等。
3.2 何謂水平切分,當(dāng)一個(gè)表中的數(shù)據(jù)量過大時(shí),我們可以把該表的數(shù)據(jù)按照某種規(guī)則,例如userID散列,進(jìn)行劃分,然后存儲(chǔ)到多個(gè)結(jié)構(gòu)相同的表,和不同的庫上。例如,我們的userDB中的用戶數(shù)據(jù)表中,每一個(gè)表的數(shù)據(jù)量都很大,就可以把userDB切分為結(jié)構(gòu)相同的多個(gè)userDB:part0DB、part1DB等,再將userDB上的用戶數(shù)據(jù)表userTable,切分為很多userTable:userTable0、userTable1等,然后將這些表按照一定的規(guī)則存儲(chǔ)到多個(gè)userDB上。
3.3 應(yīng)該使用哪一種方式來實(shí)施數(shù)據(jù)庫分庫分表,這要看數(shù)據(jù)庫中數(shù)據(jù)量的瓶頸所在,并綜合項(xiàng)目的業(yè)務(wù)類型進(jìn)行考慮。
如果數(shù)據(jù)庫是因?yàn)楸硖喽斐珊A繑?shù)據(jù),并且項(xiàng)目的各項(xiàng)業(yè)務(wù)邏輯劃分清晰、低耦合,那么規(guī)則簡單明了、容易實(shí)施的垂直切分必是首選。
而如果數(shù)據(jù)庫中的表并不多,但單表的數(shù)據(jù)量很大、或數(shù)據(jù)熱度很高,這種情況之下就應(yīng)該選擇水平切分,水平切分比垂直切分要復(fù)雜一些,它將原本邏輯上屬于一體的數(shù)據(jù)進(jìn)行了物理分割,除了在分割時(shí)要對(duì)分割的粒度做好評(píng)估,考慮數(shù)據(jù)平均和負(fù)載平均,后期也將對(duì)項(xiàng)目人員及應(yīng)用程序產(chǎn)生額外的數(shù)據(jù)管理負(fù)擔(dān)。
在現(xiàn)實(shí)項(xiàng)目中,往往是這兩種情況兼而有之,這就需要做出權(quán)衡,甚至既需要垂直切分,又需要水平切分。我們的游戲項(xiàng)目便綜合使用了垂直與水平切分,我們首先對(duì)數(shù)據(jù)庫進(jìn)行垂直切分,然后,再針對(duì)一部分表,通常是用戶數(shù)據(jù)表,進(jìn)行水平切分。
4 分庫分表存在的問題。

4.1 事務(wù)問題。
在執(zhí)行分庫分表之后,由于數(shù)據(jù)存儲(chǔ)到了不同的庫上,數(shù)據(jù)庫事務(wù)管理出現(xiàn)了困難。如果依賴數(shù)據(jù)庫本身的分布式事務(wù)管理功能去執(zhí)行事務(wù),將付出高昂的性能代價(jià);如果由應(yīng)用程序去協(xié)助控制,形成程序邏輯上的事務(wù),又會(huì)造成編程方面的負(fù)擔(dān)。
4.2 跨庫跨表的join問題。
在執(zhí)行了分庫分表之后,難以避免會(huì)將原本邏輯關(guān)聯(lián)性很強(qiáng)的數(shù)據(jù)劃分到不同的表、不同的庫上,這時(shí),表的關(guān)聯(lián)操作將受到限制,我們無法join位于不同分庫的表,也無法join分表粒度不同的表,結(jié)果原本一次查詢能夠完成的業(yè)務(wù),可能需要多次查詢才能完成。
4.3 額外的數(shù)據(jù)管理負(fù)擔(dān)和數(shù)據(jù)運(yùn)算壓力。
額外的數(shù)據(jù)管理負(fù)擔(dān),最顯而易見的就是數(shù)據(jù)的定位問題和數(shù)據(jù)的增刪改查的重復(fù)執(zhí)行問題,這些都可以通過應(yīng)用程序解決,但必然引起額外的邏輯運(yùn)算,例如,對(duì)于一個(gè)記錄用戶成績的用戶數(shù)據(jù)表userTable,業(yè)務(wù)要求查出成績最好的100位,在進(jìn)行分表之前,只需一個(gè)order by語句就可以搞定,但是在進(jìn)行分表之后,將需要n個(gè)order by語句,分別查出每一個(gè)分表的前100名用戶數(shù)據(jù),然后再對(duì)這些數(shù)據(jù)進(jìn)行合并計(jì)算,才能得出結(jié)果。

下面是分庫分表產(chǎn)生的問題,及注意事項(xiàng)

  1. 分庫分表維度的問題
    假如用戶購買了商品,需要將交易記錄保存取來,如果按照用戶的緯度分表,則每個(gè)用戶的交易記錄都保存在同一表中,所以很快很方便的查找到某用戶的購買情況,但是某商品被購買的情況則很有可能分布在多張表中,查找起來比較麻煩。反之,按照商品維度分表,可以很方便的查找到此商品的購買情況,但要查找到買人的交易記錄比較麻煩。
    所以常見的解決方式有:
    a.通過掃表的方式解決,此方法基本不可能,效率太低了。
    b.記錄兩份數(shù)據(jù),一份按照用戶緯度分表,一份按照商品維度分表。
    c.通過搜索引擎解決,但如果實(shí)時(shí)性要求很高,又得關(guān)系到實(shí)時(shí)搜索。
  2. 聯(lián)合查詢的問題
    聯(lián)合查詢基本不可能,因?yàn)殛P(guān)聯(lián)的表有可能不在同一數(shù)據(jù)庫中。
  3. 避免跨庫事務(wù)
    避免在一個(gè)事務(wù)中修改db0中的表的時(shí)候同時(shí)修改db1中的表,一個(gè)是操作起來更復(fù)雜,效率也會(huì)有一定影響。
  4. 盡量把同一組數(shù)據(jù)放到同一DB云服務(wù)器
    例如將賣家a的商品和交易信息都放到db0中,當(dāng)db1掛了的時(shí)候,賣家a相關(guān)的東西可以正常使用。也就是說避免數(shù)據(jù)庫中的數(shù)據(jù)依賴另一數(shù)據(jù)庫中的數(shù)據(jù)。
    一主多備
    在實(shí)際的應(yīng)用中,絕大部分情況都是讀遠(yuǎn)大于寫。Mysql提供了讀寫分離的機(jī)制,所有的寫操作都必須對(duì)應(yīng)到Master,讀操作可以在Master和Slave機(jī)器上進(jìn)行,Slave與Master的結(jié)構(gòu)完全一樣,一個(gè)Master可以有多個(gè)Slave,甚至Slave下還可以掛Slave,通過此方式可以有效的提高DB集群的QPS.
    所有的寫操作都是先在Master上操作,然后同步更新到Slave上,所以從Master同步到Slave機(jī)器有一定的延遲,當(dāng)系統(tǒng)很繁忙的時(shí)候,延遲問題會(huì)更加嚴(yán)重,Slave機(jī)器數(shù)量的增加也會(huì)使這個(gè)問題更加嚴(yán)重。
    此外,可以看出Master是集群的瓶頸,當(dāng)寫操作過多,會(huì)嚴(yán)重影響到Master的穩(wěn)定性,如果Master掛掉,整個(gè)集群都將不能正常工作。
    所以,1. 當(dāng)讀壓力很大的時(shí)候,可以考慮添加Slave機(jī)器的分式解決,但是當(dāng)Slave機(jī)器達(dá)到一定的數(shù)量就得考慮分庫了。 2. 當(dāng)寫壓力很大的時(shí)候,就必須得進(jìn)行分庫操作。

MySQL使用為什么要分庫分表?
可以用說用到MySQL的地方,只要數(shù)據(jù)量一大, 馬上就會(huì)遇到一個(gè)問題,要分庫分表.
這里引用一個(gè)問題為什么要分庫分表呢?MySQL處理不了大的表嗎?
其實(shí)是可以處理的大表的.我所經(jīng)歷的項(xiàng)目中單表物理上文件大小在80G多,單表記錄數(shù)在5億以上,而且這個(gè)表
屬于一個(gè)非常核用的表:朋友關(guān)系表.
但這種方式可以說不是一個(gè)最佳方式. 因?yàn)槊媾R文件系統(tǒng)如Ext3文件系統(tǒng)對(duì)大于大文件處理上也有許多問題.
這個(gè)層面可以用xfs文件系統(tǒng)進(jìn)行替換.但MySQL單表太大后有一個(gè)問題是不好解決: 表結(jié)構(gòu)調(diào)整相關(guān)的操作基
本不在可能.所以大項(xiàng)在使用中都會(huì)面監(jiān)著分庫分表的應(yīng)用.
從Innodb本身來講數(shù)據(jù)文件的Btree上只有兩個(gè)鎖, 葉子節(jié)點(diǎn)鎖和子節(jié)點(diǎn)鎖,可以想而知道,當(dāng)發(fā)生頁拆分或是添加
新葉時(shí)都會(huì)造成表里不能寫入數(shù)據(jù).
所以分庫分表還就是一個(gè)比較好的選擇了.
那么分庫分表多少合適呢?
經(jīng)測試在單表1000萬條記錄一下,寫入讀取性能是比較好的. 這樣在留點(diǎn)buffer,那么單表全是數(shù)據(jù)字型的保持在
800萬條記錄以下, 有字符型的單表保持在500萬以下.
如果按 100庫100表來規(guī)劃,如用戶業(yè)務(wù):
500萬100100 = 50000000萬 = 5000億記錄.
心里有一個(gè)數(shù)了,按業(yè)務(wù)做規(guī)劃還是比較容易的.

對(duì)于上文關(guān)于MySQL分庫分表的使用方法,大家覺得是自己想要的嗎?如果想要了解更多相關(guān),可以繼續(xù)關(guān)注我們的行業(yè)資訊板塊。

向AI問一下細(xì)節(jié)

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

AI