分庫和分表解決了什么問題我碟?
把以前存在一個(gè)數(shù)據(jù)庫實(shí)例里的數(shù)據(jù)拆分成多個(gè)數(shù)據(jù)庫實(shí)例,部署在不同的服務(wù)器中姚建,這是分庫矫俺。
分庫是為了解決服務(wù)器資源受單機(jī)限制,頂不住高并發(fā)訪問的問題,把請(qǐng)求分配到多臺(tái)服務(wù)器上厘托,降低服務(wù)器壓力友雳。
把以前存在一張表里面的數(shù)據(jù)拆分成多張表,這是分表铅匹。
分表是為了解決由于單張表數(shù)據(jù)量多大押赊,而導(dǎo)致查詢慢的問題。
一般怎么分庫包斑?
一般分庫都是按照業(yè)務(wù)劃分的流礁,比如訂單庫、用戶庫舰始。
分庫會(huì)帶來哪些問題崇棠?
事務(wù)問題
關(guān)系型數(shù)據(jù)庫,有很大一點(diǎn)在于它保證事務(wù)完整性丸卷,分庫之后單機(jī)事務(wù)就用不上了枕稀,必須使用分布式事務(wù)來解決。-
連表JOIN 查詢問題
在一個(gè)庫中的時(shí)候我們還可以利用 JOIN 來連表查詢谜嫉,而跨庫了之后就無法使用 JOIN 了萎坷。解決辦法:- 就是在業(yè)務(wù)代碼中進(jìn)行關(guān)聯(lián),也就是先把一個(gè)表的數(shù)據(jù)查出來沐兰,然后通過得到的結(jié)果再去查另一張表哆档,然后利用代碼來關(guān)聯(lián)得到最終的結(jié)果。
- 適當(dāng)?shù)娜哂嘁恍┳侄巫〈常苊釰OIN操作
一般怎么分表
-
垂直分表
垂直分表的原理比較簡單瓜浸,一般就是把某幾列拆成一個(gè)新表,這樣單行數(shù)據(jù)就會(huì)變小比原,B+樹里的單個(gè)數(shù)據(jù)頁(固定16kb)內(nèi)能放入的行數(shù)就會(huì)變多插佛,從而使單表能放入更多的數(shù)據(jù)。這樣內(nèi)存存放更多有用的數(shù)據(jù)量窘,就減少了磁盤的訪問次數(shù)雇寇,性能就得到提升。垂直分表.png
-
水平分表
水平分表.png分表算法可以分為:Hash 路由蚌铜,范圍路由锨侯,路由表
-
Hash 路由
其實(shí)就是選擇表中的某一列,然后進(jìn)行 Hash 運(yùn)算冬殃,將 Hash 運(yùn)算得到的結(jié)果再對(duì)子表數(shù)進(jìn)行取模囚痴,這樣就能均勻的將數(shù)據(jù)分到不同的子表上。- 優(yōu)點(diǎn)是:
數(shù)據(jù)分布均勻 - 缺點(diǎn)是:
就是增加子表的時(shí)候麻煩审葬,得重新映射數(shù)據(jù)
- 優(yōu)點(diǎn)是:
范圍路由
其實(shí)很簡單渡讼,可以是時(shí)間骂束,也可以是地址,表示一定的范圍的即可成箫。
比如本來一張 User 表,我可以分 User_HZ旨枯、User_BJ蹬昌、User_SH,按照地名來劃分 User攀隔。
比如 log 表皂贩,我可以將表分為 log_202103、 log_202104昆汹,把日志按照年月來劃分明刷。路由表
是專門搞個(gè)表來記錄路由信息,一般不怎么用满粗。
-
分表會(huì)帶來哪些問題辈末?
垂直分表還好,就是查詢數(shù)據(jù)需要關(guān)聯(lián)一下映皆。
水平分表會(huì)帶來很多問題:
- 排序挤聘、count、分頁問題
如果一個(gè)用戶的數(shù)據(jù)被拆分到多個(gè)表中捅彻,那查詢結(jié)果分頁就不像以前單張表那樣直接就能查出來了组去,像 count 操作也是一樣的。
- 全局主鍵的問題
以前單表的時(shí)候很簡單步淹,就是主鍵自增从隆,現(xiàn)在分表了之后就有點(diǎn)尷尬了,所以需要一些手段來保證全局主鍵唯一缭裆。- 還是自增键闺,只不過自增步長設(shè)置一下。比如現(xiàn)在有三張表幼驶,步長設(shè)置為3艾杏,三張表 ID 初始值分別是1、2盅藻、3购桑。 這樣第一張表的 ID 增長是 1、4氏淑、7勃蜘。第二張表是2、5假残、8缭贡。第三張表是3炉擅、6、9阳惹,這樣就不會(huì)重復(fù)了谍失。
- UUID,這種最簡單莹汤,但是不連續(xù)的主鍵插入會(huì)導(dǎo)致嚴(yán)重的頁分裂快鱼,性能比較差。
- 分布式 ID纲岭,比較出名的就是 Twitter 開源的 sonwflake 雪花算法抹竹。