什么是分庫分表?它有哪些實現類型?

假如你正在使用關系型數據庫開發一款健康類系統。業務發展很好,系統有很多活躍的新老用戶,這些用戶會和平臺的醫生團隊進行交互,每天可能會生成數萬甚至數十萬級別的業務數據。這樣的話,隨著數據量越來越大,系統中的某些數據表的訪問就會出現瓶頸,最典型的就是用于保存用戶和醫生日常交流數據的健康咨詢表:


雖然從理論上講,像健康咨詢表這樣位于關系型數據庫中的單個表可以存儲的數據能夠達到億條級別,但這時候訪問性能就會變得很差。業界普遍認為,諸如MySQL這樣的主流數據庫,單表容量在千萬以下是一項最佳實踐,一旦超過這個量級,就需要考慮采用其他方案。那么問題就來了,我們如何應對日益增長的數據量呢?有沒有成熟的解決方案呢?

答案是肯定的,這就是我們接下來要引入的分庫分表技術。所謂分庫分表,你可以簡單理解為:將原來獨立的數據庫拆分成若干數據庫,將原來數據量大的單個表拆分成若干個數據表,使得單一數據庫、單一數據表的數據量變得足夠小,從而達到提升數據庫性能的效果。有時候,我們也把分庫分表統稱為是一種數據分片技術,因為從概念上講,無論是分庫還是分表,都是把一定數據劃分成不同的數據片,并存儲在不同的目標對象中。

講到這里,你實際上已經明確了一點,無論是分庫還是分表,本質上體現的都是一種對現有數據進行拆分的思想,而這種拆分思想又有兩種不同的實現策略,即垂直拆分和水平拆分:


相比水平拆分,垂直拆分相對比較容易理解和實現,所以我們先來討論這種拆分策略。在健康類系統中,用戶在查看健康咨詢表數據時,位于健康咨詢首頁的諸如咨詢編號、醫生編號等基礎數據的訪問頻率顯然要比咨詢詳情等明細數據更高,因為用戶總是先定位到基礎數據,然后再選擇某一個咨詢記錄并查看明細。基于這兩種數據的不同訪問特性,我們可以把健康咨詢這種單表進行拆分,根據訪問頻次來把咨詢數據分別放在兩張表中,如下所示:


由此可以,垂直分表的處理方式就是將一個表按照字段分成多張表,每個表存儲其中一部分字段。在實現上,我們通常會把諸如詳情類的低熱度數據放在一張獨立的表中。

通過垂直分表能得到來一定程度的性能提升,但畢竟拆分后的數據仍然都是位于同一個數據庫實例中,每個表還是會競爭同一臺數據庫服務器中的CPU、內存、網絡IO等資源,性能的提升限制很多。基于這一考慮,在有了垂直分表之后,我們就可以進一步引入垂直分庫。

讓我們回到案例,針對前面介紹的場景,分表之后的健康咨詢表同樣還是跟健康用戶表等其他數據表存放在同一臺服務器中。基于垂直分庫思想,這時候,我們就可以把健康咨詢相關的數據表單獨拆分出來,放在一個獨立的數據庫中,如下圖所示:


上圖的效果就是垂直分庫。從定義上講,垂直分庫是指將表進行分類,然后分布到不同的數據庫實例上。顯然,在高并發場景下,垂直分庫能夠一定程度的提升IO訪問效率和數據庫連接數,并降低單機硬件資源的瓶頸。

從前面的分析中我們不難明白,垂直拆分盡管實現起來比較簡單,但并不能解決單表數據量過大這一核心問題。所以,現實中我們往往需要在垂直拆分的基礎上再添加水平拆分機制。例如,我們可以對健康咨詢庫中的健康咨詢表數據按照用戶編號進行取模,然后分別存儲在不同的數據庫中,這就是水平分庫的常見做法,如下所示:


可以看到,水平分庫是把同一個表的數據按一定規則拆分到不同的數據庫實例中。如果采用了上圖中的水平分庫方案,系統復雜度就會比垂直分庫要高很多,因為我們就不得不面臨一個問題,即如何知道目標數據位于哪一個數據庫中呢?這就需要引入路由規則的概念。像上圖中根據“用戶編號以3取模”就是一條路由規則。

那么,我們如何來設計并實現這些路由規則呢?業界也存在一系列路由算法,常見的包括范圍限定算法、預定義算法以及前面介紹的取模算法:


參照水平分庫的思路,我們也可以對用戶庫中的用戶表進行水平拆分,效果如下所示。也就是說,水平分表是在同一個數據庫內,把同一個表的數據按一定規則拆到多個表中。


到現在為止,我們已經把分庫分表的基本概念梳理了一遍。你會發現這些概念理解起來并不是很復雜,但如何實現這些概念呢?你可以自己從零開始打造一套分庫分表的實現工具,但顯然并沒有看上去那么簡單,而我也不推薦你重復造輪子。幸好,目前業界已經存在一批分庫分表的實現方案,主要分成客戶端類分庫分表和代理服務類分庫分表兩大類,接下去我也來介紹一下。


所謂客戶端類分庫分表,相當于在使用數據庫的客戶端應用程序中就完成了數據分片的實現。針對這種方案,因為沒有獨立的服務器組件,所以結構上比較簡單。在Java世界中,通常做法會把客戶端分片相關的處理邏輯單獨抽離出來封裝成一個獨立的工具包,從而避免業務代碼和分庫分表邏輯過于耦合。而這個獨立工具包的構建方法通常就是覆寫現有的JDBC規范,這樣,業務開發人員還是使用與JDBC規范完全兼容的一套API來操作數據庫,但這套API的背后卻自動完成了分庫分表操作,效果如下:


這種解決方案的優勢在于分庫分表操作對于業務而言是完全透明的。這樣,普通業務開發人員只需要理解JDBC規范就可以自行實現分庫分表,開發難度以及代碼維護成本得到降低。

另一方面,代理服務類分庫分表的解決方案也比較明確,顧名思義,就是采用了代理機制,也就是說在應用層和數據庫層之間添加一個代理層。有了代理層之后,對內我們就可以把分片規則集中維護在這個代理層中,對外則同樣提供與JDBC兼容的API給到應用層,其效果如下所示:


顯然,代理服務器分庫分表方案的優點在于解放了業務開發人員對分庫分表規則的管理工作,而缺點就是添加了一層代理層,一方面會因為新增了一層網絡傳輸而對性能產生一定的影響;另一方面,通常也需要專門的運維人員來確保代理服務器本身的穩定性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39823.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39823.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39823.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何在返利App中進行高效的異常處理與監控

如何在返利App中進行高效的異常處理與監控 大家好,我是微賺淘客系統3.0的小編,也是冬天不穿秋褲,天冷也要風度的程序猿! 在開發返利App過程中,高效的異常處理與監控是確保系統穩定性和用戶體驗的關鍵。本文將深入探討…

被?絡罪犯利?的5?ChatGPT越獄提?

?ChatGPT發布的近18個月以來,?絡罪犯們已經能夠利??成式AI進?攻擊。OpenAI在其內容政策中制定了限制措施,以阻??成惡意內容。作為回應,攻擊者們創建了??的?成式AI平臺,如 WormGPT和FraudGPT,并且他們還分享了…

IP地址定位中多源數據融合的應用

IP地址定位如今在諸如網絡安全、地理信息服務、智能交通等領域發揮著關鍵作用。然而,傳統的基于單一數據源(如IP數據庫)的定位方法往往存在精度有限、可靠性不足等問題。多源數據融合技術的出現為解決這些問題提供了新的思路和方法。今天我們…

石墨烯分散液制備方法眾多 應用領域廣泛

石墨烯分散液制備方法眾多 應用領域廣泛 石墨烯分散液指將石墨烯納米片均勻分散在特定溶劑中制成的溶液。石墨烯分散液具有化學穩定性好、生物相容性好、熱穩定性好等優勢,未來有望在涂料、纖維制品、電池制造、油墨等領域獲得廣泛應用。 石墨烯分散液以石墨…

深入解析某音item_search_video接口:技術原理與應用探索

item_search_video接口是某音提供的一個用于根據關鍵詞搜索相關視頻內容的API。通過該接口,用戶可以獲取到與搜索關鍵詞相關的視頻列表,包括視頻的基本信息(如標題、描述、封面圖URL)、發布者信息以及視頻的播放和互動數據等。這為…

絕區零卡頓嚴重、延遲高的解決方法提前看

絕區零這款游戲背后是一個錯綜復雜的架空世界,仿佛一幅波瀾壯闊的史詩畫卷緩緩展開。在這個世界中,神秘莫測的“空洞”災害如影隨形,給大地帶來了無盡的破壞和混沌。經過米哈游團隊的精心雕琢,無論是畫面UI的細膩呈現,…

C++ 左值右值

文章目錄 概述左值右值右值引用左值和右值的互換 小結 概述 左值和右值屬于2中不同的表達式類型;它們在表達式中扮演不同的角色,特別是在賦值操作和函數參數傳遞中。 左值 定義:左值是指那些在內存中有確定位置的表達式,可以出…

灌區量測水管理系統是如何實現灌區節水?

隨著全球水資源日益緊張,節水已成為農業生產中不可忽視的一環。在灌區管理中,量測水管理系統以其精準的數據監測和科學的灌溉管理,為實現灌區節水提供了強有力的技術支持。 灌區量測水管理系統是一套集成了自動化監測、數據傳輸、數據分析和…

Springboot交流論壇網站00304

Springboot交流論壇網站 摘要 隨著信息技術在管理上越來越深入而廣泛的應用,管理信息系統的實施在技術上已逐步成熟。本文介紹了交流論壇網站的開發全過程。通過分析交流論壇網站管理的不足,創建了一個計算機管理交流論壇網站的方案。文章介紹了交流論壇…

x-ray投影圖文件.raw轉換成.tif文件【python代碼】

如下: path 輸入文件所在的文件夾路徑import os import numpy as np import tifffile as tiffdef read_raw_data(path, dimensions, dtype):"""讀取 .raw 文件并返回圖像數據:param path: .raw 文件路徑:param dimensions: 圖像的行數和列數 (hei…

elementui中table組件合并行(看就懂)

做一個動態合并的table表格, 如下圖 1.首先定義需要合并的字段及合并后的對象 data(){return {mergeFields: [name, amount3],mergeObj: {}} }2.分配合并項函數, data為數據源 //獲取合并序號getSpanArr(data []) {this.mergeFields.forEach(key > {// 用來記錄合并行的起…

數據類型的分類和查看

數據類型是指定程序在運行過程中,將各種數據根據表示形式和組織形式劃分為不同的分類。 例如,一個人的姓名可以用字符類型存儲,年齡可以用數值類型存儲,而婚否可以用布爾類型存儲,這些都是 Python 中的 標準數據類型…

為什么我感覺 C 語言在 Linux 下執行效率比 Windows 快得多?

在開始前剛好我有一些資料,是我根據網友給的問題精心整理了一份「Linux的資料從專業入門到高級教程」, 點個關注在評論區回復“888”之后私信回復“888”,全部無償共享給大家!!!Windows的終端或者叫控制臺…

c++初級-2-引用

文章目錄 引用一、引用的定義二、引用做函數參數三、引用作為返回對象四、引用的本質五、常量引用 引用 即給一個變量起別名。 一、引用的定義 int a 10;//引用int& b a;cout << "a " << a << endl;cout << "b " <&l…

時間12小時和24時轉換方法

24小時時間轉為12小時制 function convertTo12Hour(time24h){let [hours, minutes] time24h.split(:);let modifier 上午;if (parseInt(hours, 10) > 12) {modifier 下午;hours (parseInt(hours, 10) - 12).toString();}if (parseInt(hours, 10) 12) {modifier 下午;}…

新手入門:無服務器函數和FaaS簡介

無服務器&#xff08;Serverless&#xff09;架構的價值在于其成本效益、彈性和擴展性、簡化的開發和部署流程、高可用性和可靠性以及使開發者能夠專注于業務邏輯。通過自動化資源調配和按需計費&#xff0c;無服務器架構能夠降低成本并適應流量變化&#xff0c;同時簡化開發流…

《昇思25天學習打卡營第01天|sun65535》

開始 昇思25天打卡訓練營&#xff0c;讓我第一次了解了華為昇思的平臺&#xff0c;之前也有自己本地使用4060訓練了一些“小模型”&#xff0c;但是都是比較皮毛的知識&#xff0c;只是根據教程去搭建。很少了解到具體的過程。昇思25天打卡訓練營給了一個比較全面的訓練課程。…

大數據基礎知識【大數據導論】

各位大佬好 &#xff0c;這里是阿川的博客&#xff0c;祝您變得更強 個人主頁&#xff1a;在線OJ的阿川 大佬的支持和鼓勵&#xff0c;將是我成長路上最大的動力 阿川水平有限&#xff0c;如有錯誤&#xff0c;歡迎大佬指正 大數據基礎知識前 必看 【大數據導論】—大數據序言…

Golang | Leetcode Golang題解之第206題反轉鏈表

題目&#xff1a; 題解&#xff1a; func reverseList(head *ListNode) *ListNode {if head nil || head.Next nil {return head}newHead : reverseList(head.Next)head.Next.Next headhead.Next nilreturn newHead }

vue3基于uni-app 封裝小程序request請求

const BASE_URL https://47.122.26.142; // 替換為你的 API 基礎 URL const token uni.getStorageSync(token);const request (url: string, method: any, data {}, headers {}) > {return new Promise((resolve, reject) > {uni.request({url: ${BASE_URL}${url},m…