2021-Java后端工程師面試指南-(MySQL)

前言

文本已收錄至我的GitHub倉(cāng)庫(kù),歡迎Star:https://github.com/bin392328206/six-finger
種一棵樹(shù)最好的時(shí)間是十年前,其次是現(xiàn)在

Tips

面試指南系列,很多情況下不會(huì)去深挖細(xì)節(jié),是小六六以被面試者的角色去回顧知識(shí)的一種方式,所以我默認(rèn)大部分的東西,作為面試官的你,肯定是懂的。

https://www.processon.com/view/link/600ed9e9637689349038b0e4

上面的是腦圖地址

叨絮

可能大家覺(jué)得有點(diǎn)老生常談了,確實(shí)也是。面試題,面試寶典,隨便一搜,根本看不完,也看不過(guò)來(lái),那我寫(xiě)這個(gè)的意義又何在呢?其實(shí)嘛我寫(xiě)這個(gè)的有以下的目的

  • 第一就是通過(guò)一個(gè)體系的復(fù)習(xí),讓自己前面的寫(xiě)的文章再重新的過(guò)一遍,總結(jié)升華嘛
  • 第二就是通過(guò)寫(xiě)文章幫助大家建立一個(gè)復(fù)習(xí)體系,我會(huì)將大部分會(huì)問(wèn)的的知識(shí)點(diǎn)以點(diǎn)帶面的形式給大家做一個(gè)導(dǎo)論

然后下面是前面的文章匯總

今天大家一起來(lái)復(fù)習(xí)復(fù)習(xí)MySQL吧

聊聊MySql的結(jié)構(gòu)吧

大體來(lái)說(shuō),MySQL 可以分為 Server 層和存儲(chǔ)引擎層兩部分。

Server 層包括連接器、查詢(xún)緩存、分析器、優(yōu)化器、執(zhí)行器等,涵蓋 MySQL 的大多數(shù)核心服 務(wù)功能,以及所有的內(nèi)置函數(shù)(如日期、時(shí)間、數(shù)學(xué)和加密函數(shù)等),所有跨存儲(chǔ)引擎的功能都 在這一層實(shí)現(xiàn),比如存儲(chǔ)過(guò)程、觸發(fā)器、視圖等。

而存儲(chǔ)引擎層負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和提取。其架構(gòu)模式是插件式的,支持 InnoDB、MyISAM、 Memory 等多個(gè)存儲(chǔ)引擎。現(xiàn)在最常用的存儲(chǔ)引擎是 InnoDB,它從 MySQL 5.5.5 版本開(kāi)始成 為了默認(rèn)存儲(chǔ)引擎。

聊聊InnoDB和MyISAM的區(qū)別吧

  • 第一個(gè)也是最重要的一個(gè) InnoDB支持事務(wù),MyISAM不支持
  • 在MySQL中,表級(jí)鎖有兩種模式:表共享讀鎖,表獨(dú)占寫(xiě)鎖。也就是說(shuō)對(duì)于MyISAM引擎的表,多個(gè)用戶(hù)可以對(duì)同一個(gè)表發(fā)起讀的請(qǐng)求,但是如果一個(gè)用戶(hù)對(duì)表進(jìn)行寫(xiě)操作,那么則會(huì)阻塞其他用戶(hù)對(duì)這個(gè)表的讀和寫(xiě)。InnoDB引擎的表是通過(guò)索引項(xiàng)來(lái)加鎖實(shí)現(xiàn)的,即只有通過(guò)索引條件檢索數(shù)據(jù)的時(shí)候,InnoDB才會(huì)使用行級(jí)鎖,否則也會(huì)使用表級(jí)鎖。
  • InnoDB聚集索引,MyISAM 非聚集索引
  • 企業(yè)級(jí)生成環(huán)境強(qiáng)制用InnoDB,所以下面的面試題都是基于InnoDB。

說(shuō)說(shuō)一個(gè)查詢(xún)SQL的執(zhí)行過(guò)程

  • 連接器:首先肯定和mysql建立連接的過(guò)程
  • 查詢(xún)緩存:在8以前,mysql會(huì)把相同的sql,緩存起來(lái),但是因?yàn)榘l(fā)現(xiàn)效率不是那么好,8之后刪除了
  • 分析器: 如果沒(méi)有命中查詢(xún)緩存,就要開(kāi)始真正執(zhí)行語(yǔ)句了。首先,MySQL 需要知道你要做什么,因此 需要對(duì) SQL 語(yǔ)句做解析
  • 優(yōu)化器:優(yōu)化器是在表里面有多個(gè)索引的時(shí)候,決定使用哪個(gè)索引
  • 執(zhí)行器:MySQL 通過(guò)分析器知道了你要做什么,通過(guò)優(yōu)化器知道了該怎么做,于是就進(jìn)入了執(zhí)行器階 段,開(kāi)始執(zhí)行語(yǔ)句
  • 返回?cái)?shù)據(jù)給到客戶(hù)端

說(shuō)說(shuō)一條SQL的插入流程

update T set c=c+1 where ID=2;

  • 執(zhí)行器先找引擎取 ID=2 這一行。ID 是主鍵,引擎直接用樹(shù)搜索找到這一行。如果 ID=2 這一行所在的數(shù)據(jù)頁(yè)本來(lái)就在內(nèi)存中,就直接返回給執(zhí)行器;否則,需要先從磁盤(pán)讀入內(nèi) 存,然后再返回。
  • 執(zhí)行器拿到引擎給的行數(shù)據(jù),把這個(gè)值加上 1,比如原來(lái)是 N,現(xiàn)在就是 N+1,得到新的 一行數(shù)據(jù),再調(diào)用引擎接口寫(xiě)入這行新數(shù)據(jù)。
  • 引擎將這行新數(shù)據(jù)更新到內(nèi)存中,同時(shí)將這個(gè)更新操作記錄到 redo log 里面,此時(shí) redo log 處于 prepare 狀態(tài)。然后告知執(zhí)行器執(zhí)行完成了,隨時(shí)可以提交事務(wù)
  • 執(zhí)行器生成這個(gè)操作的 binlog,并把 binlog 寫(xiě)入磁盤(pán)。
  • 執(zhí)行器調(diào)用引擎的提交事務(wù)接口,引擎把剛剛寫(xiě)入的 redo log 改成提交(commit)狀 態(tài),更新完成。

說(shuō)說(shuō)Buffer Pool吧

  • 它是mysql 一個(gè)非常重要的內(nèi)存組件,因?yàn)槭窃趦?nèi)存中操作的,所以速度比較快
  • 建議設(shè)置合理的buffer pool的大小,如果大小在內(nèi)存的百分60合適
  • 要明確的是pool的結(jié)構(gòu)是一頁(yè)一頁(yè)的
  • 如果內(nèi)存夠大,可以多設(shè)計(jì)幾個(gè)pool

Buffer Pool臟數(shù)據(jù)頁(yè)到底為什么會(huì)臟

  • 是因?yàn)槲覀冃略?更新 刪除操作的時(shí)候只是對(duì)內(nèi)存進(jìn)行操作,和對(duì)我們r(jià)edo log日志進(jìn)行操作,所以呢就會(huì)有臟數(shù)據(jù)
  • 在buffer pool里面 有一個(gè)維護(hù)臟數(shù)據(jù)頁(yè)的雙向鏈表,用來(lái)明確哪個(gè)數(shù)據(jù)頁(yè)需要刷
  • 然后還有就是lru鏈表,就是假設(shè)我們的pool滿了,那么我們肯定要把一些數(shù)據(jù)刪除,就是lru算法了(基于冷熱數(shù)據(jù)分離的思想的lru)

說(shuō)說(shuō)InnoDB頁(yè)

InnoDB是一個(gè)將表中的數(shù)據(jù)存儲(chǔ)到磁盤(pán)上的存儲(chǔ)引擎,所以即使關(guān)機(jī)后重啟我們的數(shù)據(jù)還是存在的。而真正處理數(shù)據(jù)的過(guò)程是發(fā)生在內(nèi)存中的,所以需要把磁盤(pán)中的數(shù)據(jù)加載到內(nèi)存中,如果是處理寫(xiě)入或修改請(qǐng)求的話,還需要把內(nèi)存中的內(nèi)容刷新到磁盤(pán)上。而我們知道讀寫(xiě)磁盤(pán)的速度非常慢,和內(nèi)存讀寫(xiě)差了幾個(gè)數(shù)量級(jí),所以當(dāng)我們想從表中獲取某些記錄時(shí),InnoDB存儲(chǔ)引擎需要一條一條的把記錄從磁盤(pán)上讀出來(lái)么?不,那樣會(huì)慢死,InnoDB采取的方式是:將數(shù)據(jù)劃分為若干個(gè)頁(yè),以頁(yè)作為磁盤(pán)和內(nèi)存之間交互的基本單位,InnoDB中頁(yè)的大小一般為 16 KB。也就是在一般情況下,一次最少?gòu)拇疟P(pán)中讀取16KB的內(nèi)容到內(nèi)存中,一次最少把內(nèi)存中的16KB內(nèi)容刷新到磁盤(pán)中。

說(shuō)說(shuō)InnoDB行格式是怎么樣的

就是我們mysql里面一行的數(shù)據(jù),再innodb里面分為了2個(gè)部分

  • 一個(gè)是我們?cè)嫉臄?shù)據(jù),真實(shí)的數(shù)據(jù),也就是列的值
  • 還有一個(gè)額外的數(shù)據(jù) 一個(gè)是變長(zhǎng)字段的列表,一個(gè)是NUll值,還有一個(gè)是記錄頭信息

聊聊整個(gè)磁盤(pán)的存儲(chǔ)的結(jié)構(gòu)

首先是InnoDB的頁(yè)存儲(chǔ)結(jié)構(gòu),我們知道最大的結(jié)構(gòu)是表,表里面可以分為很多個(gè)區(qū),每個(gè)區(qū)里面又有很多的頁(yè) 多個(gè)不同的頁(yè)組成的是一個(gè)雙向鏈表,而每個(gè)頁(yè)里面的數(shù)據(jù)行會(huì)按主鍵的大小組成一個(gè)單向鏈表,并且每4到8個(gè)數(shù)據(jù)組成一個(gè)槽,每個(gè)槽存儲(chǔ)在pageDirectoy里面 ,當(dāng)我們要查詢(xún)頁(yè)的行數(shù)據(jù)的時(shí)候,可以先定位到頁(yè),然后用2分法定位到槽,然后遍歷槽,來(lái)定位到當(dāng)前行的數(shù)據(jù)。

聊聊索引吧

首先哈 索引的本質(zhì)是什么呢?其實(shí)索引就是一直加快磁盤(pán)查詢(xún)速度的一些數(shù)據(jù)結(jié)構(gòu),因?yàn)槲覀兇疟P(pán)i/o的性能比較慢,索引可以加快我們的查詢(xún)速度。

聊聊有哪些數(shù)據(jù)結(jié)構(gòu)適合做索引結(jié)構(gòu)的,優(yōu)缺點(diǎn)是什么

  • Hash索引:hash表,我相信大家都很熟悉了,他的優(yōu)點(diǎn)查詢(xún)速度快,但是他不支持范圍查詢(xún),哈希表這種結(jié)構(gòu)適用于只有等值查詢(xún)的場(chǎng)景
  • 二叉樹(shù):如果數(shù)據(jù)多了,樹(shù)高會(huì)很高,查詢(xún)的成本就會(huì)隨著樹(shù)高的增加而增加。
  • B樹(shù):B樹(shù)已經(jīng)是不錯(cuò)的一個(gè)索引結(jié)構(gòu)了,但是他的子節(jié)點(diǎn)也存儲(chǔ)數(shù)據(jù),所以還是不能控制數(shù)高,因?yàn)闃?shù)的高度,其實(shí)就是代表我們的io
  • B+樹(shù):其實(shí)很簡(jiǎn)單,我們看一下上面的數(shù)據(jù)結(jié)構(gòu),最開(kāi)始的Hash不支持范圍查詢(xún),二叉樹(shù)樹(shù)高很高,只有B樹(shù)跟B+有的一比。B樹(shù)一個(gè)節(jié)點(diǎn)可以存儲(chǔ)多個(gè)元素,相對(duì)于完全平衡二叉樹(shù)整體的樹(shù)高降低了,磁盤(pán)IO效率提高了。而B(niǎo)+樹(shù)是B樹(shù)的升級(jí)版,只是把非葉子節(jié)點(diǎn)冗余一下,這么做的好處是為了提高范圍查找的效率。

你可以說(shuō)說(shuō)InnoDB 的索引模型嗎?

  • 主鍵索引,在 InnoDB 里,主鍵索引也被稱(chēng)為聚簇索引
  • 普通索引,就是我們一般的索引
  • 唯一索引,具體排他性的索引
  • 組合索,可以多個(gè)列的索引

說(shuō)說(shuō)怎么從磁盤(pán)上加載數(shù)據(jù),也就是查詢(xún)的執(zhí)行方式

MySQL的查詢(xún)的執(zhí)行方式大致分為下邊兩種:

  • 使用全表掃描進(jìn)行查詢(xún)
  • 使用索引進(jìn)行查詢(xún)
    • 針對(duì)主鍵或唯一二級(jí)索引的等值查詢(xún)
    • 針對(duì)普通二級(jí)索引的等值查詢(xún)
    • 針對(duì)索引列的范圍查詢(xún)
    • 直接掃描整個(gè)索引

磁盤(pán)訪問(wèn)方式的分類(lèi)

  • const:通過(guò)主鍵或者唯一二級(jí)索引列與常數(shù)的等值比較來(lái)定位一條記錄
  • ref:對(duì)于某個(gè)包含多個(gè)索引列的二級(jí)索引來(lái)說(shuō),只要是最左邊的連續(xù)索引列是與常數(shù)的等值比較就可能采用ref的訪問(wèn)方法
  • range:類(lèi)似于范圍查詢(xún)的方式
  • index:這個(gè)是什么意思呢?就是比如我們的where條件不符合查詢(xún)的索引,但是查詢(xún)的條件在一個(gè)組合索引中,那我們遍歷索引數(shù),比遍歷數(shù)據(jù)數(shù)要快。
  • all:最直接的查詢(xún)執(zhí)行方式就是全表掃描,對(duì)于InnoDB表來(lái)說(shuō)也就是直接掃描聚簇索引.

說(shuō)說(shuō)常見(jiàn)的sql需要注意到的點(diǎn),也就是sql優(yōu)化

  • 對(duì)查詢(xún)進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
  • 應(yīng)盡量避免在 where 子句中對(duì)字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描
  • 應(yīng)盡量避免在 where 子句中使用!=或<>操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描。
  • 盡量避免在 where 子句中使用 or 來(lái)連接條件,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如:
  • 應(yīng)盡量避免在where子句中對(duì)字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描
  • 不要在 where 子句中的“=”左邊進(jìn)行函數(shù)、算術(shù)運(yùn)算或其他表達(dá)式運(yùn)算,否則系統(tǒng)將可能無(wú)法正確使用索引
  • 并不是所有索引對(duì)查詢(xún)都有效,SQL是根據(jù)表中數(shù)據(jù)來(lái)進(jìn)行查詢(xún)優(yōu)化的,當(dāng)索引列有大量數(shù)據(jù)重復(fù)時(shí),SQL查詢(xún)可能不會(huì)去利用索引,如一表中有字段sex,male、female幾乎各一半,那么即使在sex上建了索引也對(duì)查詢(xún)效率起不了作用。
  • 索引并不是越多越好,索引固然可以提高相應(yīng)的 select 的效率,但同時(shí)也降低了 insert 及 update 的效率,因?yàn)?insert 或 update 時(shí)有可能會(huì)重建索引,所以怎樣建索引需要慎重考慮,視具體情況而定。一個(gè)表的索引數(shù)最好不要超過(guò)6個(gè),若太多則應(yīng)考慮一些不常使用到的列上建的索引是否有必要
  • 任何地方都不要使用 select * from t ,用具體的字段列表代替“*”,不要返回用不到的任何字段
  • 盡量避免大事務(wù)操作,提高系統(tǒng)并發(fā)能力
  • 盡量避免向客戶(hù)端返回大數(shù)據(jù)量,若數(shù)據(jù)量過(guò)大,應(yīng)該考慮相應(yīng)需求是否合理。
  • 最左原則,是設(shè)計(jì)組合索引的原則。
  • 盡可能的使用 varchar/nvarchar 代替 char/nchar ,因?yàn)槭紫茸冮L(zhǎng)字段存儲(chǔ)空間小,可以節(jié)省存儲(chǔ)空間,其次對(duì)于查詢(xún)來(lái)說(shuō),在一個(gè)相對(duì)較小的字段內(nèi)搜索效率顯然要高些。

說(shuō)說(shuō)EXPLAIN關(guān)鍵字吧

小六六挑選幾個(gè)有參考價(jià)值的列來(lái)說(shuō)說(shuō)。

  • id 每個(gè)單查詢(xún)都有,id越大越先執(zhí)行,id相同表示加載表的順序是從上到下。
  • type :這個(gè)字段就是我們前面說(shuō)的查詢(xún)的分類(lèi)了 重點(diǎn)關(guān)注
  • possible_keys 可能的索引
  • key 實(shí)際用到的索引 重點(diǎn)關(guān)注
  • key_len 實(shí)際使用的索引長(zhǎng)度
  • rows 預(yù)估要讀取的行數(shù) 重點(diǎn)關(guān)注
  • Extra 額外的信息 比如看是否用到回表 Using index,或者是否用到了臨時(shí)表之類(lèi)的

說(shuō)說(shuō)count(字段) count(主鍵 id) count(1) count(*)

  • count(主鍵 id) ,InnoDB 引擎會(huì)遍歷整張表,把每一行的 id 值都取出來(lái),返回給server 層。server 層拿到 id 后,判斷是不可能為空的,就按行累加
  • count(1) ,InnoDB 引擎遍歷整張表,但不取值。server 層對(duì)于返回的每一行,放一個(gè)數(shù)字“1”進(jìn)去,判斷是不可能為空的,按行累加。
  • count(字段),如果這個(gè)“字段”是定義為 not null 的話,一行行地從記錄里面讀出這個(gè)字段,判斷不能為 null,按行累加;
  • count() ,并不會(huì)把全部字段取出來(lái),而是專(zhuān)門(mén)做了優(yōu)化,不取值。count() 肯定不是 null,按行累加
  • 按照效率排序的話,count(字段)<count(主鍵 id)<count(1)≈count(),所以我建議你,盡量使用 count()。

事務(wù)

說(shuō)說(shuō)mysql的事務(wù)吧

ACID 這個(gè)肯定得背的

  • 原子性(A):事務(wù)是最小單位,不可再分
  • 一致性?:事務(wù)要求所有的DML語(yǔ)句操作的時(shí)候,必須保證同時(shí)成功或者同時(shí)失敗
  • 隔離性(I):事務(wù)A和事務(wù)B之間具有隔離性
  • 持久性(D):是事務(wù)的保證,事務(wù)終結(jié)的標(biāo)志(內(nèi)存的數(shù)據(jù)持久到硬盤(pán)文件中)

聊聊它的隔離級(jí)別吧

  • 讀未提交 會(huì)發(fā)生臟讀
  • 讀已提交 會(huì)發(fā)生 不可重復(fù)讀
  • 可重復(fù)讀 會(huì)發(fā)生 幻讀
  • 串行化,沒(méi)有問(wèn)題

說(shuō)說(shuō)sping默認(rèn)的事務(wù)傳播級(jí)別

  • Spring中事務(wù)的默認(rèn)實(shí)現(xiàn)使用的是AOP,也就是代理的方式,如果大家在使用代碼測(cè)試時(shí),同一個(gè)Service類(lèi)中的方法相互調(diào)用需要使用注入的對(duì)象來(lái)調(diào)用,不要直接使用this.方法名來(lái)調(diào)用,this.方法名調(diào)用是對(duì)象內(nèi)部方法調(diào)用,不會(huì)通過(guò)Spring代理,也就是事務(wù)不會(huì)起作用
  • REQUIRED(Spring默認(rèn)的事務(wù)傳播類(lèi)型),如果當(dāng)前沒(méi)有事務(wù),則自己新建一個(gè)事務(wù),如果當(dāng)前存在事務(wù),則加入這個(gè)事務(wù),這個(gè)我們一般用的最多
  • SUPPORTS 當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù),如果當(dāng)前沒(méi)有事務(wù),就以非事務(wù)方法執(zhí)行
  • MANDATORY 當(dāng)前存在事務(wù),則加入當(dāng)前事務(wù),如果當(dāng)前事務(wù)不存在,則拋出異常。
  • REQUIRES_NEW 創(chuàng)建一個(gè)新事務(wù),如果存在當(dāng)前事務(wù),則掛起該事務(wù)。
  • NOT_SUPPORTED 始終以非事務(wù)方式執(zhí)行,如果當(dāng)前存在事務(wù),則掛起當(dāng)前事務(wù)

說(shuō)說(shuō)MVCC唄,談?wù)勀阕约旱目捶?/h3>
  • 在Mysql的InnoDB引擎中就是指在已提交讀(READ COMMITTD)和可重復(fù)讀(REPEATABLE READ)這兩種隔離級(jí)別下的事務(wù)對(duì)于SELECT操作會(huì)訪問(wèn)版本鏈中的記錄的過(guò)程。
  • 在InnoDB引擎表中,它的聚簇索引記錄中有兩個(gè)必要的隱藏列: trx_id和roll_pointer
  • mvcc通過(guò)排它鎖的形式來(lái)修改數(shù)據(jù)
  • 修改之前會(huì)把數(shù)據(jù)放到undolog日志,如果事務(wù)提交,那就條件到數(shù)據(jù)里面,如果事務(wù)回滾,則放棄這個(gè)事務(wù)鏈
  • 讀已提交和可重復(fù)讀的MVcc的區(qū)別就是 再這個(gè)事務(wù)級(jí)別下,一個(gè)事務(wù)操作里面每次查詢(xún)都會(huì)生成一個(gè)新的視圖,更新自己最小事務(wù)id和最大事務(wù)id,然后可重復(fù)讀不會(huì),它只會(huì)在事務(wù)開(kāi)始的時(shí)候生成一個(gè)一致性視圖。

Mysql的主從架構(gòu)聊聊

說(shuō)說(shuō)什么是mysql主從復(fù)制?

主從復(fù)制是指將主數(shù)據(jù)庫(kù)的DDL和DML操作通過(guò)二進(jìn)制日志傳到從數(shù)據(jù)庫(kù)上,然后在從數(shù)據(jù)庫(kù)上對(duì)這些日志進(jìn)行重新執(zhí)行,從而使從數(shù)據(jù)庫(kù)和主數(shù)據(jù)庫(kù)的數(shù)據(jù)保持一致。

那你聊聊主從復(fù)制的原理

  • MySql主庫(kù)在事務(wù)提交時(shí)會(huì)把數(shù)據(jù)變更作為事件記錄在二進(jìn)制日志Binlog中;
  • 主庫(kù)推送二進(jìn)制日志文件Binlog中的事件到從庫(kù)的中繼日志Relay Log中,之后從庫(kù)根據(jù)中繼日志重做數(shù)據(jù)變更操作,通過(guò)邏輯復(fù)制來(lái)達(dá)到主庫(kù)和從庫(kù)的數(shù)據(jù)一致性;
  • MySql通過(guò)三個(gè)線程來(lái)完成主從庫(kù)間的數(shù)據(jù)復(fù)制,其中Binlog Dump線程跑在主庫(kù)上,I/O線程和SQL線程跑著從庫(kù)上;
  • 當(dāng)在從庫(kù)上啟動(dòng)復(fù)制時(shí),首先創(chuàng)建I/O線程連接主庫(kù),主庫(kù)隨后創(chuàng)建Binlog Dump線程讀取數(shù)據(jù)庫(kù)事件并發(fā)送給I/O線程,I/O線程獲取到事件數(shù)據(jù)后更新到從庫(kù)的中繼日志Relay Log中去,之后從庫(kù)上的SQL線程讀取中繼日志Relay Log中更新的數(shù)據(jù)庫(kù)事件并應(yīng)用,如下圖所示。

聊聊Mysql的分庫(kù)分表吧

首先來(lái)說(shuō)說(shuō)分庫(kù)分表的各種類(lèi)型吧

  • 垂直分表:這個(gè)就是我們說(shuō)的把大表變成小表,也就是分字段
  • 水平分表,就是說(shuō)我們把數(shù)據(jù)分到多個(gè)表里面
  • 按月分表,也就是這些數(shù)據(jù)不會(huì)變了,然后按時(shí)間分。查詢(xún)的時(shí)候不能跨月查詢(xún)
  • 分庫(kù)的話,一般現(xiàn)在一個(gè)庫(kù)就是一個(gè)服務(wù)(按業(yè)務(wù)分庫(kù)),這樣分,或者是多個(gè)庫(kù)一個(gè)服務(wù)(按表分庫(kù))

說(shuō)說(shuō)常用的分庫(kù)分表中間件

  • mycat:阿里開(kāi)源的,但是目前生態(tài)不那么好了,
  • Sharding Sphere 這個(gè)很好,融合了Sharding-JDBC、Sharding-Proxy、Sharding-Sidecar 文檔齊全
  • 其實(shí)分庫(kù)分表你不用中間件自己也能做,就是他們也是代理的模式幫你去聚合查詢(xún),如果你有5個(gè)庫(kù),那你要查排序,是不是每個(gè)庫(kù)都要查出來(lái),最后總的合起來(lái)排序這樣。分頁(yè)這些都是,實(shí)現(xiàn)起來(lái)還是很麻煩
  • ShardingSphere-JDBC 在 Java 的 JDBC 層提供的額外服務(wù)。 它使用客戶(hù)端直連數(shù)據(jù)庫(kù),以 jar 包形式提供服務(wù),無(wú)需額外部署和依賴(lài),可理解為增強(qiáng)版的 JDBC 驅(qū)動(dòng),完全兼容 JDBC 和各種 ORM 框架。
  • ShardingSphere-Proxy 是 Apache ShardingSphere 的第二個(gè)產(chǎn)品。 它定位為透明化的數(shù)據(jù)庫(kù)代理端,提供封裝了數(shù)據(jù)庫(kù)二進(jìn)制協(xié)議的服務(wù)端版本,用于完成對(duì)異構(gòu)語(yǔ)言的支持。

說(shuō)說(shuō)如何滿足“跨越多個(gè)水平切分?jǐn)?shù)據(jù)庫(kù),且分庫(kù)依據(jù)與排序依據(jù)為不同屬性,并需要進(jìn)行分頁(yè)”的查詢(xún)需求

  • 服務(wù)層通過(guò)uid取模將數(shù)據(jù)分布到兩個(gè)庫(kù)上去之后,每個(gè)數(shù)據(jù)庫(kù)都失去了全局視野,數(shù)據(jù)按照time局部排序之后由于不清楚到底是哪種情況,所以必須每個(gè)庫(kù)都返回3頁(yè)數(shù)據(jù)
  • 業(yè)務(wù)折衷法-禁止跳頁(yè)查詢(xún) 用正常的方法取得第一頁(yè)數(shù)據(jù),并得到第一頁(yè)記錄的time_max

結(jié)束

Mysql就這些吧,也不是很全,分庫(kù)分表有很多實(shí)戰(zhàn),但是我們?cè)诠居玫膆base,所以對(duì)于這塊涉及沒(méi)有那么多,接下來(lái)Redis吧

日常求贊

好了各位,以上就是這篇文章的全部?jī)?nèi)容了,能看到這里的人呀,都是真粉。

創(chuàng)作不易,各位的支持和認(rèn)可,就是我創(chuàng)作的最大動(dòng)力,我們下篇文章見(jiàn)

微信 搜 "六脈神劍的程序人生" 回復(fù)888 有我找的許多的資料送給大家

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容