0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

分庫(kù)分表的21條法則速來(lái)碼住(上)

jf_78858299 ? 來(lái)源:程序員小富 ? 作者:程序員內(nèi)點(diǎn)事 ? 2023-05-26 17:33 ? 次閱讀

(一)好好的系統(tǒng),為什么要分庫(kù)分表?

還是不著急實(shí)戰(zhàn),咱們先介紹下在分庫(kù)分表架構(gòu)實(shí)施過(guò)程中,會(huì)接觸到的一些通用概念,了解這些概念能夠幫助理解市面上其他的分庫(kù)分表工具,盡管它們的實(shí)現(xiàn)方法可能存在差異,但整體思路基本一致。因此,在開(kāi)始實(shí)際操作之前,我們有必要先掌握這些通用概念,以便更好地理解和應(yīng)用分庫(kù)分表技術(shù)。

我們結(jié)合具體業(yè)務(wù)場(chǎng)景,以t_order表為例進(jìn)行架構(gòu)優(yōu)化。由于數(shù)據(jù)量已經(jīng)達(dá)到億級(jí)別,查詢(xún)性能?chē)?yán)重下降,因此我們采用了分庫(kù)分表技術(shù)來(lái)處理這個(gè)問(wèn)題。具體而言,我們將原本的單庫(kù)分成了兩個(gè)庫(kù),分別為DB_1DB_2,并在每個(gè)庫(kù)中再次進(jìn)行分表處理,生成t_order_1t_order_2兩張表,實(shí)現(xiàn)對(duì)訂單表的分庫(kù)分表處理。

圖片

數(shù)據(jù)分片

通常我們?cè)谔岬椒謳?kù)分表的時(shí)候,大多是以水平切分模式(水平分庫(kù)、分表)為基礎(chǔ)來(lái)說(shuō)的,數(shù)據(jù)分片它將原本一張數(shù)據(jù)量較大的表 t_order 拆分生成數(shù)個(gè)表結(jié)構(gòu)完全一致的小數(shù)據(jù)量表(拆分表) t_order_0、t_order_1、···、t_order_n,每張表只存儲(chǔ)原大表中的一部分?jǐn)?shù)據(jù)。

圖片

數(shù)據(jù)節(jié)點(diǎn)

數(shù)據(jù)節(jié)點(diǎn)是數(shù)據(jù)分片中一個(gè)不可再分的最小單元(表),它由數(shù)據(jù)源名稱(chēng)和數(shù)據(jù)表組成,例如上圖中 DB_1.t_order_1DB_2.t_order_2 就表示一個(gè)數(shù)據(jù)節(jié)點(diǎn)。

圖片

邏輯表

邏輯表是指具有相同結(jié)構(gòu)的水平拆分表的邏輯名稱(chēng)。

比如我們將訂單表t_order 分表拆分成 t_order_0 ··· t_order_9等10張表,這時(shí)我們的數(shù)據(jù)庫(kù)中已經(jīng)不存在 t_order這張表,取而代之的是若干的t_order_n表。

分庫(kù)分表通常對(duì)業(yè)務(wù)代碼都是無(wú)侵入式的,開(kāi)發(fā)者只專(zhuān)注于業(yè)務(wù)邏輯SQL編碼,我們?cè)诖a中SQL依然按 t_order來(lái)寫(xiě),而在執(zhí)行邏輯SQL前將其解析成對(duì)應(yīng)的數(shù)據(jù)庫(kù)真實(shí)執(zhí)行的SQL。此時(shí) t_order 就是這些拆分表的邏輯表。

業(yè)務(wù)邏輯SQL

select * from t_order where order_no='A11111'

真實(shí)執(zhí)行SQL

select * from DB_1.t_order_n where order_no='A11111'

真實(shí)表

真實(shí)表就是在數(shù)據(jù)庫(kù)中真實(shí)存在的物理表DB_1.t_order_n。

圖片

廣播表

廣播表是一類(lèi)特殊的表,其表結(jié)構(gòu)和數(shù)據(jù)在所有分片數(shù)據(jù)源中均完全一致。與拆分表相比,廣播表的數(shù)據(jù)量較小、更新頻率較低,通常用于字典表或配置表等場(chǎng)景。由于其在所有節(jié)點(diǎn)上都有副本,因此可以大大降低JOIN關(guān)聯(lián)查詢(xún)的網(wǎng)絡(luò)開(kāi)銷(xiāo),提高查詢(xún)效率。

需要注意的是,對(duì)于廣播表的修改操作需要保證同步性,以確保所有節(jié)點(diǎn)上的數(shù)據(jù)保持一致。

廣播表的特點(diǎn)

  • 在所有分片數(shù)據(jù)源中,廣播表的數(shù)據(jù)完全一致。因此,對(duì)廣播表的操作(如插入、更新和刪除)會(huì)實(shí)時(shí)在每個(gè)分片數(shù)據(jù)源中執(zhí)行一遍,以保證數(shù)據(jù)的一致性。
  • 對(duì)于廣播表的查詢(xún)操作,僅需要在任意一個(gè)分片數(shù)據(jù)源中執(zhí)行一次即可。
  • 與任何其他表進(jìn)行JOIN操作都是可行的,因?yàn)橛捎趶V播表的數(shù)據(jù)在所有節(jié)點(diǎn)上均一致,所以可以訪問(wèn)到任何一個(gè)節(jié)點(diǎn)上的相同數(shù)據(jù)。

什么樣的表可以作為廣播表呢?

訂單管理系統(tǒng)中,往往需要查詢(xún)統(tǒng)計(jì)某個(gè)城市地區(qū)的訂單數(shù)據(jù),這就會(huì)涉及到省份地區(qū)表t_city與訂單流水表DB_n.t_order_n進(jìn)行JOIN查詢(xún),因此可以考慮將省份地區(qū)表設(shè)計(jì)為廣播表,核心理念就是 避免跨庫(kù)JOIN操作 。

圖片

注意 :上邊我們提到廣播表在數(shù)據(jù)插入、更新與刪除會(huì)實(shí)時(shí)在每個(gè)分片數(shù)據(jù)源均執(zhí)行,也就是說(shuō)如果你有1000個(gè)分片數(shù)據(jù)源,那么修改一次廣播表就要執(zhí)行1000次SQL,所以盡量不在并發(fā)環(huán)境下和業(yè)務(wù)高峰時(shí)進(jìn)行,以免影響系統(tǒng)的性能。

單表

單表指所有的分片數(shù)據(jù)源中僅唯一存在的表(沒(méi)有分片的表),適用于數(shù)據(jù)量不大且無(wú)需分片的表。

如果一張表的數(shù)據(jù)量預(yù)估在千萬(wàn)級(jí)別,且沒(méi)有與其他拆分表進(jìn)行關(guān)聯(lián)查詢(xún)的需求,建議將其設(shè)置為單表類(lèi)型,存儲(chǔ)在默認(rèn)分片數(shù)據(jù)源中。

分片鍵

分片鍵決定了數(shù)據(jù)落地的位置,也就是數(shù)據(jù)將會(huì)被分配到哪個(gè)數(shù)據(jù)節(jié)點(diǎn)上存儲(chǔ)。因此,分片鍵的選擇非常重要。

比如我們將 t_order 表進(jìn)行分片后,當(dāng)插入一條訂單數(shù)據(jù)執(zhí)行SQL時(shí),需要通過(guò)解析SQL語(yǔ)句中指定的分片鍵來(lái)計(jì)算數(shù)據(jù)應(yīng)該落在哪個(gè)分片中。以表中order_no字段為例,我們可以通過(guò)對(duì)其取模運(yùn)算(比如 order_no % 2)來(lái)得到分片編號(hào),然后根據(jù)分片編號(hào)分配數(shù)據(jù)到對(duì)應(yīng)的數(shù)據(jù)庫(kù)實(shí)例(比如 DB_1DB_2)。拆分表也是同理計(jì)算。

在這個(gè)過(guò)程中,order_no 就是 t_order 表的分片鍵。也就是說(shuō),每一條訂單數(shù)據(jù)的 order_no 值決定了它應(yīng)該存放的數(shù)據(jù)庫(kù)實(shí)例和表。選擇一個(gè)適合作為分片鍵的字段可以更好地利用水平分片帶來(lái)的性能提升。

圖片

這樣同一個(gè)訂單的相關(guān)數(shù)據(jù)就會(huì)落在同一個(gè)數(shù)據(jù)庫(kù)、表中,查詢(xún)訂單時(shí)同理計(jì)算,就可直接定位數(shù)據(jù)位置,大幅提升數(shù)據(jù)檢索的性能,避免了全庫(kù)表掃描。

不僅如此 ShardingSphere 還支持根據(jù)多個(gè)字段作為分片健進(jìn)行分片,這個(gè)在后續(xù)對(duì)應(yīng)章節(jié)中會(huì)詳細(xì)講。

分片策略

分片策略來(lái)指定使用哪種分片算法、選擇哪個(gè)字段作為分片鍵以及如何將數(shù)據(jù)分配到不同的節(jié)點(diǎn)上。

分片策略是由分片算法分片健組合而成,分片策略中可以使用多種分片算法和對(duì)多個(gè)分片鍵進(jìn)行運(yùn)算。

圖片

分庫(kù)、分表的分片策略配置是相對(duì)獨(dú)立的,可以各自使用不同的策略與算法,每種策略中可以是多個(gè)分片算法的組合,每個(gè)分片算法可以對(duì)多個(gè)分片健做邏輯判斷。

分片算法

分片算法則是用于對(duì)分片鍵進(jìn)行運(yùn)算,將數(shù)據(jù)劃分到具體的數(shù)據(jù)節(jié)點(diǎn)中。

常用的分片算法有很多:

  • 哈希分片 :根據(jù)分片鍵的哈希值來(lái)決定數(shù)據(jù)應(yīng)該落到哪個(gè)節(jié)點(diǎn)上。例如,根據(jù)用戶(hù) ID 進(jìn)行哈希分片,將屬于同一個(gè)用戶(hù)的數(shù)據(jù)分配到同一個(gè)節(jié)點(diǎn)上,便于后續(xù)的查詢(xún)操作。
  • 范圍分片 :分片鍵值按區(qū)間范圍分配到不同的節(jié)點(diǎn)上。例如,根據(jù)訂單創(chuàng)建時(shí)間或者地理位置來(lái)進(jìn)行分片。
  • 取模分片 :將分片鍵值對(duì)分片數(shù)取模,將結(jié)果作為數(shù)據(jù)應(yīng)該分配到的節(jié)點(diǎn)編號(hào)。例如, order_no % 2 將訂單數(shù)據(jù)分到兩個(gè)節(jié)點(diǎn)之一。
  • .....

實(shí)際業(yè)務(wù)開(kāi)發(fā)中分片的邏輯要復(fù)雜的多,不同的算法適用于不同的場(chǎng)景和需求,需要根據(jù)實(shí)際情況進(jìn)行選擇和調(diào)整。

綁定表

綁定表是那些具有相同分片規(guī)則的一組分片表,由于分片規(guī)則一致所產(chǎn)生的的數(shù)據(jù)落地位置相同,在JOIN聯(lián)合查詢(xún)時(shí)能有效避免跨庫(kù)操作。

比如:t_order 訂單表和 t_order_item 訂單項(xiàng)目表,都以 order_no 字段作為分片鍵,并且使用 order_no 進(jìn)行關(guān)聯(lián),因此兩張表互為綁定表關(guān)系。

使用綁定表進(jìn)行多表關(guān)聯(lián)查詢(xún)時(shí),必須使用分片鍵進(jìn)行關(guān)聯(lián),否則會(huì)出現(xiàn)笛卡爾積關(guān)聯(lián)或跨庫(kù)關(guān)聯(lián),從而影響查詢(xún)效率。

當(dāng)使用 t_ordert_order_item 表進(jìn)行多表聯(lián)合查詢(xún),執(zhí)行如下聯(lián)合查詢(xún)的邏輯SQL。

SELECT * FROM t_order o JOIN t_order_item i ON o.order_no=i.order_no

如果不配置綁定表關(guān)系,兩個(gè)表的數(shù)據(jù)位置不確定就會(huì)全庫(kù)表查詢(xún),出現(xiàn)笛卡爾積關(guān)聯(lián)查詢(xún),將產(chǎn)生如下四條SQL。

SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_no=i.order_no 
SELECT * FROM t_order_0 o JOIN t_order_item_1 i ON o.order_no=i.order_no 
SELECT * FROM t_order_1 o JOIN t_order_item_0 i ON o.order_no=i.order_no 
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_no=i.order_no

圖片

而配置綁定表關(guān)系后再進(jìn)行關(guān)聯(lián)查詢(xún)時(shí),分片規(guī)則一致產(chǎn)生的數(shù)據(jù)就會(huì)落到同一個(gè)庫(kù)表中,那么只需在當(dāng)前庫(kù)中 t_order_nt_order_item_n 表關(guān)聯(lián)即可。

SELECT * FROM t_order_0 o JOIN t_order_item_0 i ON o.order_id=i.order_id 
SELECT * FROM t_order_1 o JOIN t_order_item_1 i ON o.order_id=i.order_id

圖片

注意 :在關(guān)聯(lián)查詢(xún)時(shí) t_order 它作為整個(gè)聯(lián)合查詢(xún)的主表。所有相關(guān)的路由計(jì)算都只使用主表的策略,t_order_item 表的分片相關(guān)的計(jì)算也會(huì)使用 t_order 的條件,所以要保證綁定表之間的分片鍵要完全相同。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • SQL
    SQL
    +關(guān)注

    關(guān)注

    1

    文章

    772

    瀏覽量

    44193
  • 路由
    +關(guān)注

    關(guān)注

    0

    文章

    278

    瀏覽量

    41883
  • 架構(gòu)
    +關(guān)注

    關(guān)注

    1

    文章

    517

    瀏覽量

    25507
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    數(shù)據(jù)庫(kù)分區(qū)、分庫(kù)

    今天先說(shuō)說(shuō)數(shù)據(jù)庫(kù)的數(shù)據(jù)分區(qū),分庫(kù)以及的內(nèi)容吧! 數(shù)據(jù)庫(kù)分區(qū)、分庫(kù) 數(shù)據(jù)庫(kù)分區(qū)、
    的頭像 發(fā)表于 09-30 11:24 ?2879次閱讀

    談分布式數(shù)據(jù)庫(kù)中間件之分庫(kù)   

      分庫(kù),顧名思義就是把原本存儲(chǔ)于一個(gè)庫(kù)的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)庫(kù),把原本存儲(chǔ)于一個(gè)的數(shù)據(jù)分塊存儲(chǔ)到多個(gè)
    發(fā)表于 08-02 20:19

    10PCB設(shè)計(jì)黃金法則

    時(shí)應(yīng)牢記并踐行的十最有效的設(shè)計(jì)法則。工程師無(wú)需按時(shí)間先后或相對(duì)重要性依次執(zhí)行這些法則,只需全部遵循便可極大地改變產(chǎn)品設(shè)計(jì)?! ?b class='flag-5'>法則一:選擇正確的網(wǎng)格 - 設(shè)置并始終使用能夠匹配最多元
    發(fā)表于 09-21 16:46

    分庫(kù)是什么?怎么實(shí)現(xiàn)?

    數(shù)據(jù)庫(kù)分庫(kù)、讀寫(xiě)分離的原理實(shí)現(xiàn),使用場(chǎng)景
    發(fā)表于 10-25 17:24

    買(mǎi)大硬盤(pán)的6法則

    買(mǎi)大硬盤(pán)的6法則 采購(gòu)話題1:別光顧容量和價(jià)格!         沒(méi)錯(cuò),容量和價(jià)格是大家在選購(gòu)硬盤(pán)時(shí)問(wèn)得最多的關(guān)鍵詞。事實(shí),除了這兩
    發(fā)表于 12-17 14:39 ?1030次閱讀

    利用Mycat實(shí)現(xiàn)MySQL讀寫(xiě)分離、分庫(kù)最佳實(shí)踐

    利用Mycat實(shí)現(xiàn)MySQL讀寫(xiě)分離、分庫(kù)最佳實(shí)踐
    發(fā)表于 09-08 10:20 ?14次下載
    利用Mycat實(shí)現(xiàn)MySQL讀寫(xiě)分離、<b class='flag-5'>分庫(kù)</b><b class='flag-5'>分</b><b class='flag-5'>表</b>最佳實(shí)踐

    數(shù)據(jù)庫(kù)分庫(kù)基礎(chǔ)和實(shí)踐

    因?yàn)閱螐埍砝锩娴臄?shù)據(jù)多。如果是因?yàn)?b class='flag-5'>表多而數(shù)據(jù)多,使用垂直切分,根據(jù)業(yè)務(wù)切分成不同的庫(kù)。如果是因?yàn)閱螐?b class='flag-5'>表的數(shù)據(jù)量太大,這時(shí)要用水平切分,即把的數(shù)據(jù)按某種規(guī)則切分成多張,甚至多個(gè)庫(kù)
    發(fā)表于 09-05 16:40 ?264次閱讀

    你們知道為什么要分庫(kù)

    在文章開(kāi)頭先拋幾個(gè)問(wèn)題: (1)什么時(shí)候才需要分庫(kù)呢?我們的評(píng)判標(biāo)準(zhǔn)是什么? (2)一張存儲(chǔ)了多少數(shù)據(jù)的時(shí)候,才需要考慮分庫(kù)
    的頭像 發(fā)表于 08-16 10:37 ?1548次閱讀

    優(yōu)化MySQL數(shù)據(jù)庫(kù)中樸實(shí)無(wú)華的和花里胡哨的分庫(kù)

    blog.csdn.net/qq_39390545/article/details/116248222 一、樸實(shí)無(wú)華的 - 1、垂直 2、水平分
    的頭像 發(fā)表于 08-26 16:33 ?1274次閱讀

    你是否知道分庫(kù)需要哪些要素?

    分庫(kù)會(huì)重新影響數(shù)據(jù)的分布,無(wú)論是全量還是增量,都會(huì)涉及到數(shù)據(jù)遷移,所以Databus是必要的。
    的頭像 發(fā)表于 10-12 10:39 ?801次閱讀

    什么是分庫(kù)?為什么分庫(kù)?什么情況下會(huì)用分庫(kù)呢?

    分庫(kù)是由分庫(kù)這兩個(gè)獨(dú)立概念組成的,只不過(guò)通常分庫(kù)
    的頭像 發(fā)表于 11-30 09:37 ?7586次閱讀

    PCB布局的十設(shè)計(jì)法則

    本文以下內(nèi)容介紹了電子設(shè)計(jì)工程師在使用設(shè)計(jì)軟件進(jìn)行PCB布局設(shè)計(jì)及商業(yè)制造時(shí)應(yīng)牢記并踐行的十最有效的設(shè)計(jì)法則。工程師無(wú)需按時(shí)間先后或相對(duì)重要性依次執(zhí)行這些法則,只需全部遵循便可極大地改變產(chǎn)品設(shè)計(jì)。
    發(fā)表于 04-08 11:19 ?314次閱讀

    分庫(kù)21法則速來(lái)(下)

    還是不著急實(shí)戰(zhàn),咱們先介紹下在分庫(kù)架構(gòu)實(shí)施過(guò)程中,會(huì)接觸到的一些通用概念,了解這些概念能夠幫助理解市面上其他的分庫(kù)表工具,盡管它們的實(shí)
    的頭像 發(fā)表于 05-26 17:33 ?650次閱讀
    <b class='flag-5'>分庫(kù)</b><b class='flag-5'>分</b><b class='flag-5'>表</b>的<b class='flag-5'>21</b><b class='flag-5'>條</b><b class='flag-5'>法則</b><b class='flag-5'>速來(lái)</b><b class='flag-5'>碼</b><b class='flag-5'>住</b>(下)

    分庫(kù)后復(fù)雜查詢(xún)的應(yīng)對(duì)之道:基于DTS實(shí)時(shí)性ES寬構(gòu)建技術(shù)實(shí)踐

    ,通過(guò)分庫(kù)應(yīng)對(duì)存系統(tǒng)讀寫(xiě)性能瓶頸和存儲(chǔ)瓶頸;分庫(kù)
    的頭像 發(fā)表于 06-25 18:30 ?891次閱讀
    <b class='flag-5'>分庫(kù)</b><b class='flag-5'>分</b><b class='flag-5'>表</b>后復(fù)雜查詢(xún)的應(yīng)對(duì)之道:基于DTS實(shí)時(shí)性ES寬<b class='flag-5'>表</b>構(gòu)建技術(shù)實(shí)踐

    軟件系統(tǒng)數(shù)據(jù)庫(kù)的分庫(kù)設(shè)計(jì)

    軟件系統(tǒng)數(shù)據(jù)庫(kù)的分庫(kù)設(shè)計(jì) 系統(tǒng)讀寫(xiě)分離、分庫(kù)技術(shù)實(shí)現(xiàn)采用MyCat中間件,MyCat 是
    的頭像 發(fā)表于 08-22 11:39 ?348次閱讀
    軟件系統(tǒng)數(shù)據(jù)庫(kù)的<b class='flag-5'>分庫(kù)</b><b class='flag-5'>分</b><b class='flag-5'>表</b>設(shè)計(jì)