溫馨提示×

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

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

MySQL數(shù)據(jù)庫(kù)常見面試題有哪些

發(fā)布時(shí)間:2022-04-28 10:16:38 來源:億速云 閱讀:135 作者:zzz 欄目:MySQL數(shù)據(jù)庫(kù)

本篇內(nèi)容主要講解“MySQL數(shù)據(jù)庫(kù)常見面試題有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“MySQL數(shù)據(jù)庫(kù)常見面試題有哪些”吧!

MySQL數(shù)據(jù)庫(kù)常見面試題有哪些

1、數(shù)據(jù)庫(kù)的常用范式:

  • 第一范式(1NF):指表的列不可再分,數(shù)據(jù)庫(kù)中表的每一列都是不可分割的基本數(shù)據(jù)項(xiàng),同一列中不能有多個(gè)值;

  • 第二范式(2NF):在 1NF 的基礎(chǔ)上,還包含兩部分的內(nèi)容:一是表必須有一個(gè)主鍵;二是表中非主鍵列必須完全依賴于主鍵,不能只依賴于主鍵的一部分;

  • 第三范式(3NF):在 2NF 的基礎(chǔ)上,消除非主鍵列對(duì)主鍵的傳遞依賴,非主鍵列必須直接依賴于主鍵。

  • BC范式(BCNF):在 3NF 的基礎(chǔ)上,消除主屬性對(duì)于碼部分的傳遞依賴

2、SQL語句的執(zhí)行過程:

2.1、客戶端的數(shù)據(jù)庫(kù)驅(qū)動(dòng)與數(shù)據(jù)庫(kù)連接池:

(1)客戶端與數(shù)據(jù)庫(kù)進(jìn)行通信前,通過數(shù)據(jù)庫(kù)驅(qū)動(dòng)與MySQL建立連接,建立完成之后,就發(fā)送SQL語句

(2)為了減少頻繁創(chuàng)建和銷毀連接造成系統(tǒng)性能的下降,通過數(shù)據(jù)庫(kù)連接池維護(hù)一定數(shù)量的連接線程,當(dāng)需要進(jìn)行連接時(shí),就直接從連接池中獲取,使用完畢之后,再歸還給連接池。常見的數(shù)據(jù)庫(kù)連接池有 Druid、C3P0、DBCP

2.2、MySQL架構(gòu)的Server層的執(zhí)行過程:

(1)連接器:主要負(fù)責(zé)跟客戶端建立連接、獲取權(quán)限、維持和管理連接

(2)查詢緩存:優(yōu)先在緩存中進(jìn)行查詢,如果查到了則直接返回,如果緩存中查詢不到,在去數(shù)據(jù)庫(kù)中查詢。

MySQL緩存是默認(rèn)關(guān)閉的,也就是說不推薦使用緩存,并且在MySQL8.0 版本已經(jīng)將查詢緩存的整塊功能刪掉了。這主要是它的使用場(chǎng)景限制造成的:

  • 先說下緩存中數(shù)據(jù)存儲(chǔ)格式:key(sql語句)- value(數(shù)據(jù)值),所以如果SQL語句(key)只要存在一點(diǎn)不同之處就會(huì)直接進(jìn)行數(shù)據(jù)庫(kù)查詢了;

  • 由于表中的數(shù)據(jù)不是一成不變的,大多數(shù)是經(jīng)常變化的,而當(dāng)數(shù)據(jù)庫(kù)中的數(shù)據(jù)變化了,那么相應(yīng)的與此表相關(guān)的緩存數(shù)據(jù)就需要移除掉;

(3)解析器/分析器:分析器的工作主要是對(duì)要執(zhí)行的SQL語句進(jìn)行詞法解析、語法解析,最終得到抽象語法樹,然后再使用預(yù)處理器對(duì)抽象語法樹進(jìn)行語義校驗(yàn),判斷抽象語法樹中的表是否存在,如果存在的話,在接著判斷select投影列字段是否在表中存在等。

(4)優(yōu)化器:主要將SQL經(jīng)過詞法解析、語法解析后得到的語法樹,通過數(shù)據(jù)字典和統(tǒng)計(jì)信息的內(nèi)容,再經(jīng)過一系列運(yùn)算 ,最終得出一個(gè)執(zhí)行計(jì)劃,包括選擇使用哪個(gè)索引

在分析是否走索引查詢時(shí),是通過進(jìn)行動(dòng)態(tài)數(shù)據(jù)采樣統(tǒng)計(jì)分析出來;只要是統(tǒng)計(jì)分析出來的,那就可能會(huì)存在分析錯(cuò)誤的情況,所以在SQL執(zhí)行不走索引時(shí),也要考慮到這方面的因素

(5)執(zhí)行器:根據(jù)一系列的執(zhí)行計(jì)劃去調(diào)用存儲(chǔ)引擎提供的API接口去調(diào)用操作數(shù)據(jù),完成SQL的執(zhí)行。

2.3、Innodb存儲(chǔ)引擎的執(zhí)行過程:

  • (1)首先MySQL執(zhí)行器根據(jù) 執(zhí)行計(jì)劃 調(diào)用存儲(chǔ)引擎的API查詢數(shù)據(jù)

  • (2)存儲(chǔ)引擎先從緩存池buffer pool中查詢數(shù)據(jù),如果沒有就會(huì)去磁盤中查詢,如果查詢到了就將其放到緩存池中

  • (3)在數(shù)據(jù)加載到 Buffer Pool 的同時(shí),會(huì)將這條數(shù)據(jù)的原始記錄保存到 undo 日志文件中

  • (4)innodb 會(huì)在 Buffer Pool 中執(zhí)行更新操作

  • (5)更新后的數(shù)據(jù)會(huì)記錄在 redo log buffer 中

  • (6)提交事務(wù)在提交的同時(shí)會(huì)做以下三件事

  • (7)(第一件事)將redo log buffer中的數(shù)據(jù)刷入到redo log文件中

  • (8)(第二件事)將本次操作記錄寫入到 bin log文件中

  • (9)(第三件事)將bin log文件名字和更新內(nèi)容在 bin log 中的位置記錄到redo log中,同時(shí)在 redo log 最后添加 commit 標(biāo)記

  • (10)使用一個(gè)后臺(tái)線程,它會(huì)在某個(gè)時(shí)機(jī)將我們Buffer Pool中的更新后的數(shù)據(jù)刷到 MySQL 數(shù)據(jù)庫(kù)中,這樣就將內(nèi)存和數(shù)據(jù)庫(kù)的數(shù)據(jù)保持統(tǒng)一了

3、常用的存儲(chǔ)引擎?InnoDB與MyISAM的區(qū)別?

存儲(chǔ)引擎是對(duì)底層物理數(shù)據(jù)執(zhí)行實(shí)際操作的組件,為Server服務(wù)層提供各種操作數(shù)據(jù)的API。常用的存儲(chǔ)引擎有InnoDB、MyISAM、Memory。這里我們主要介紹InnoDB 與 MyISAM 的區(qū)別:

(1)事務(wù):MyISAM不支持事務(wù),InnoDB支持事務(wù)

(2)鎖級(jí)別:MyISAM只支持表級(jí)鎖,InnoDB支持行級(jí)鎖和表級(jí)鎖,默認(rèn)使用行級(jí)鎖,但是行鎖只有通過索引查詢數(shù)據(jù)才會(huì)使用,否則將使用表鎖。行級(jí)鎖在每次獲取鎖和釋放鎖的操作需要消耗比表鎖更多的資源。使用行鎖可能會(huì)存在死鎖的情況,但是表級(jí)鎖不存在死鎖

(3)主鍵和外鍵:MyISAM 允許沒有任何索引和主鍵的表存在,不支持外鍵。InnoDB的主鍵不能為空且支持主鍵自增長(zhǎng),如果沒有設(shè)定主鍵或者非空唯一索引,就會(huì)自動(dòng)生成一個(gè)6字節(jié)的主鍵,支持外鍵完整性約束

(4)索引結(jié)構(gòu):MyISAM 和 InnoDB 都是使用B+樹索引,MyISAM的主鍵索引和輔助索引的Data域都是保存行數(shù)據(jù)記錄的地址。但是InnoDB的主鍵索引的Data域保存的不是行數(shù)據(jù)記錄的地址,而是保存該行的所有數(shù)據(jù)內(nèi)容,而輔助索引的Data域保存的則是主索引的值。

由于InnoDB的輔助索引保存的是主鍵索引的值,所以使用輔助索引需要檢索兩遍索引:首先檢索輔助索引獲得主鍵,然后用主鍵到主索引中檢索獲得記錄。這也是為什么不建議使用過長(zhǎng)的字段作為主鍵的原因:由于輔助索引包含主鍵列,所以,如果主鍵使用過長(zhǎng)的字段,將會(huì)導(dǎo)致其他輔助索變得更大,所以爭(zhēng)取盡量把主鍵定義得小一些。

(5)全文索引:MyISAM支持全文索引,InnoDB在5.6版本之前不支持全文索引,5.6版本及之后的版本開始支持全文索引

(6)表的具體行數(shù):

  • ① MyISAM:保存有表的總行數(shù),如果使用 select count() from table 會(huì)直接取出出該值,不需要進(jìn)行全表掃描。

  • ② InnoDB:沒有保存表的總行數(shù),如果使用 select count() from table 需要會(huì)遍歷整個(gè)表,消耗相當(dāng)大。

(7)存儲(chǔ)結(jié)構(gòu):

  • ① MyISAM會(huì)在磁盤上存儲(chǔ)成三個(gè)文件:.frm文件存儲(chǔ)表定義,.MYD文件存儲(chǔ)數(shù)據(jù),.MYI文件存儲(chǔ)索引。

  • ② InnoDB:把數(shù)據(jù)和索引存放在表空間里面,所有的表都保存在同一個(gè)數(shù)據(jù)文件中,InnoDB表的大小只受限于操作系統(tǒng)文件的大小,一般為2GB。

(8)存儲(chǔ)空間:

  • ① MyISAM:可被壓縮,存儲(chǔ)空間較小。支持三種不同的存儲(chǔ)格式:靜態(tài)表(默認(rèn),但是注意數(shù)據(jù)末尾不能有空格,會(huì)被去掉)、動(dòng)態(tài)表、壓縮表。

  • ② InnoDB:需要更多的內(nèi)存和存儲(chǔ),它會(huì)在主內(nèi)存中建立其專用的緩沖池用于高速緩沖數(shù)據(jù)和索引。

(9)適用場(chǎng)景:

  • ① 如果需要提供回滾、崩潰恢復(fù)能力的ACID事務(wù)能力,并要求實(shí)現(xiàn)行鎖級(jí)別并發(fā)控制,InnoDB是一個(gè)好的選擇;

  • ② 如果數(shù)據(jù)表主要用來查詢記錄,讀操作遠(yuǎn)遠(yuǎn)多于寫操作且不需要數(shù)據(jù)庫(kù)事務(wù)的支持,則MyISAM引擎能提供較高的處理效率;

備注:在mysql8.0版本中已經(jīng)廢棄了MyISAM存儲(chǔ)引擎

4、事務(wù)的ACID與實(shí)現(xiàn)原理?

數(shù)據(jù)庫(kù)的事務(wù)是并發(fā)控制的基本單位,是指邏輯上的一組操作,要么全部執(zhí)行,要么全部不執(zhí)行。

4.1、事務(wù)的ACID:

  • (1)原子性:事務(wù)是一個(gè)不可分割的工作單元,事務(wù)里的操作要么都成功,要么都失敗,如果事務(wù)執(zhí)行失敗,則需要進(jìn)行回滾。

  • (2)隔離性:事務(wù)的所操作的數(shù)據(jù)在提交之前,對(duì)其他事務(wù)的可見程度。

  • (3)持久性:一旦事務(wù)提交,它對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的改變就是永久的。

  • (4)一致性:事務(wù)不能破壞數(shù)據(jù)的完整性和業(yè)務(wù)的一致性。例如在轉(zhuǎn)賬時(shí),不管事務(wù)成功還是失敗,雙方錢的總額不變。

4.2、ACID的實(shí)現(xiàn)原理:

4.2.1、原子性:原子性是通過MySQL的回滾日志undo log實(shí)現(xiàn)的:當(dāng)事務(wù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改時(shí),InnoDB會(huì)生成對(duì)應(yīng)的undo log;如果事務(wù)執(zhí)行失敗或調(diào)用了rollback,導(dǎo)致事務(wù)需要回滾,便可以利用undo log中的信息將數(shù)據(jù)回滾到修改之前的樣子。

4.2.2、隔離性:

(1)事務(wù)的隔離級(jí)別:

為保證在并發(fā)環(huán)境下讀取數(shù)據(jù)的完整性和一致性,數(shù)據(jù)庫(kù)提供了四種事務(wù)隔離級(jí)別,隔離級(jí)別越高,越能保證數(shù)據(jù)的完整性和一致性,但對(duì)高并發(fā)性能影響也越大,執(zhí)行效率越低。(四種隔離級(jí)別從上往下依次升高)

  • 讀未提交:允許事務(wù)在執(zhí)行過程中,讀取其他事務(wù)尚未提交的數(shù)據(jù);

  • 讀已提交:允許事務(wù)在執(zhí)行過程中讀取其他事務(wù)已經(jīng)提交的數(shù)據(jù);

  • 可重復(fù)讀(默認(rèn)級(jí)別):在同一個(gè)事務(wù)內(nèi),任意時(shí)刻的查詢結(jié)果都是一致的;

  • 讀序列化:所有事務(wù)逐個(gè)依次執(zhí)行,每次讀都需要獲取表級(jí)共享鎖,讀寫會(huì)相互阻塞。

(2)事務(wù)的并發(fā)問題:

如果不考慮事務(wù)的隔離性,在事務(wù)并發(fā)的環(huán)境下,可能存在問題有:

  • 更新丟失:兩個(gè)或多個(gè)事務(wù)操作相同的數(shù)據(jù),然后基于選定的值更新該行時(shí),由于每個(gè)事務(wù)都不知道其他事務(wù)的存在,就會(huì)發(fā)生丟失更新問題:最后的更新覆蓋了其他事務(wù)所做的更新。

  • 臟讀:指事務(wù)A正在訪問數(shù)據(jù),并且對(duì)數(shù)據(jù)進(jìn)行了修改(事務(wù)未提交),這時(shí),事務(wù)B也使用這個(gè)數(shù)據(jù),后來事務(wù)A撤銷回滾,并把修改后的數(shù)據(jù)恢復(fù)原值,B讀到的數(shù)據(jù)就與數(shù)據(jù)庫(kù)中的數(shù)據(jù)不一致,即B讀到的數(shù)據(jù)是臟數(shù)據(jù)。

  • 不可重復(fù)讀:在一個(gè)事務(wù)內(nèi),多次讀取同一個(gè)數(shù)據(jù),但是由于另一個(gè)事務(wù)在此期間對(duì)這個(gè)數(shù)據(jù)做了修改并提交,導(dǎo)致前后讀取到的數(shù)據(jù)不一致;

  • 幻讀:在一個(gè)事務(wù)中,先后兩次進(jìn)行讀取相同的數(shù)據(jù)(一般是范圍查詢),但由于另一個(gè)事務(wù)新增或者刪除了數(shù)據(jù),導(dǎo)致前后兩次結(jié)果不一致。

不同的事務(wù)隔離級(jí)別,在并發(fā)環(huán)境會(huì)存在不同的并發(fā)問題:

MySQL數(shù)據(jù)庫(kù)常見面試題有哪些

(3)事務(wù)隔離性的實(shí)現(xiàn)原理:

Innodb事務(wù)的隔離級(jí)別是由MVVC和鎖機(jī)制實(shí)現(xiàn)的:

① MVCC(Multi-Version Concurrency Control,多版本并發(fā)控制)是 MySQL 的 InnoDB 存儲(chǔ)引擎實(shí)現(xiàn)事務(wù)隔離級(jí)別的一種具體方式,用于實(shí)現(xiàn)讀已提交和可重復(fù)讀這兩種隔離級(jí)別。而讀未提交隔離級(jí)別總是讀取最新的數(shù)據(jù)行,無需使用 MVCC。讀序列化隔離級(jí)別需要對(duì)所有讀取的行都加鎖,單純使用 MVCC 無法實(shí)現(xiàn)。

MVCC是通過在每行記錄后面保存兩個(gè)隱藏的列來實(shí)現(xiàn)的,一個(gè)保存了行的事務(wù)ID,一個(gè)保存了行的回滾段指針。每開始一個(gè)新的事務(wù),都會(huì)自動(dòng)遞增產(chǎn)生一個(gè)新的事務(wù)ID。事務(wù)開始時(shí)會(huì)把該事務(wù)ID放到當(dāng)前事務(wù)影響的行事務(wù)ID字段中,而回滾段的指針有該行記錄上的所有版本數(shù)據(jù),在undo log回滾日志中通過鏈表形式組織,也就是說該值實(shí)際指向undo log中該行的歷史記錄鏈表。

在并發(fā)訪問數(shù)據(jù)庫(kù)時(shí),對(duì)正在事務(wù)中的數(shù)據(jù)做MVCC多版本的管理,以避免寫操作阻塞讀操作,并且可以通過比較版本解決快照讀方式的幻讀問題,但對(duì)于當(dāng)前讀的幻讀,MVCC并不能解決,需要通過臨鍵鎖來解決。

② 鎖機(jī)制:

MySQL鎖機(jī)制的基本工作原理就是:事務(wù)在修改數(shù)據(jù)庫(kù)之前,需要先獲得相應(yīng)的鎖,獲得鎖的事務(wù)才可以修改數(shù)據(jù);在該事務(wù)操作期間,這部分的數(shù)據(jù)是鎖定,其他事務(wù)如果需要修改數(shù)據(jù),需要等待當(dāng)前事務(wù)提交或回滾后釋放鎖。

  • 排它鎖解決臟讀

  • 共享鎖解決不可重復(fù)讀

  • 臨鍵鎖解決幻讀

4.2.3、持久性:

持久性的依靠redo log日志實(shí)現(xiàn),在執(zhí)行SQL時(shí)會(huì)保存已執(zhí)行的SQL語句到一個(gè)redo log文件,但是為了提高效率,將數(shù)據(jù)寫入到redo log之前,會(huì)先寫入到內(nèi)存中的redo log buffer緩存區(qū)中。寫入過程如下:當(dāng)向數(shù)據(jù)庫(kù)寫入數(shù)據(jù)時(shí),執(zhí)行過程會(huì)首先寫入redo log buffer,redo log buffer中修改的數(shù)據(jù)會(huì)定期刷新到磁盤的redo log文件中,這一過程稱為刷盤(即redo log buffer寫日志到磁盤的redo log file中 )。

redo log buffer的使用可以大大提高了讀寫數(shù)據(jù)的效率,但是也帶了新的問題:如果MySQL宕機(jī),而此時(shí)redo log buffer中修改的數(shù)據(jù)在內(nèi)存還沒有刷新到磁盤,就會(huì)導(dǎo)致數(shù)據(jù)的丟失,事務(wù)的持久性無法保證。為了確保事務(wù)的持久性,在當(dāng)事務(wù)提交時(shí),會(huì)調(diào)用fsync接口對(duì)redo log進(jìn)行刷盤 ,刷新頻率由 innodb_flush_log_at_trx_commit變量來控制的:

  • 0:表示不刷入磁盤;

  • 1:事務(wù)每次提交的時(shí)候,就把緩沖池中的數(shù)據(jù)刷新到磁盤中;

  • 2:提交事務(wù)的時(shí)候,把緩沖池中的數(shù)據(jù)寫入磁盤文件對(duì)應(yīng)的 os cache 緩存里去,而不是直接進(jìn)入磁盤文件??赡?1 秒后才會(huì)把 os cache 里的數(shù)據(jù)寫入到磁盤文件里去。

4.2.4、一致性:

一致性指的是事務(wù)不能破壞數(shù)據(jù)的完整性和業(yè)務(wù)的一致性 :

  • 數(shù)據(jù)的完整性: 實(shí)體完整性、列完整性(如字段的類型、大小、長(zhǎng)度要符合要求)、外鍵約束等

  • 業(yè)務(wù)的一致性:例如在銀行轉(zhuǎn)賬時(shí),不管事務(wù)成功還是失敗,雙方錢的總額不變。

5、數(shù)據(jù)庫(kù)中的鎖機(jī)制?

當(dāng)數(shù)據(jù)庫(kù)中多個(gè)事務(wù)并發(fā)存取同一數(shù)據(jù)的時(shí)候,若對(duì)并發(fā)操作不加控制就可能會(huì)讀取和存儲(chǔ)不正確的數(shù)據(jù),破壞數(shù)據(jù)庫(kù)的一致性。MySQL鎖機(jī)制的基本工作原理就是,事務(wù)在修改數(shù)據(jù)庫(kù)之前,需要先獲得相應(yīng)的鎖,獲得鎖的事務(wù)才可以修改數(shù)據(jù);在該事務(wù)操作期間,這部分的數(shù)據(jù)是鎖定,其他事務(wù)如果需要修改數(shù)據(jù),需要等待當(dāng)前事務(wù)提交或回滾后釋放鎖。

按照不同的分類方式,鎖的種類可以分為以下幾種:

  • 按鎖的粒度劃分:表級(jí)鎖、行級(jí)鎖、頁級(jí)鎖;

  • 按鎖的類型劃分:共享(鎖S鎖)、排他鎖(X鎖);

  • 按鎖的使用策略劃分:樂觀鎖、悲觀鎖;

5.1、表級(jí)鎖、行級(jí)鎖、頁級(jí)鎖:

  • 表級(jí)鎖:最大粒度的鎖級(jí)別,發(fā)生鎖沖突的概率最高,并發(fā)度最低,但開銷小,加鎖快,不會(huì)出現(xiàn)死鎖;

  • 行級(jí)鎖:最小粒度的所級(jí)別,發(fā)生鎖沖突的概率最小,并發(fā)度最高,但開銷大,加鎖慢,會(huì)發(fā)生死鎖;

  • 頁級(jí)鎖:鎖粒度界于表級(jí)鎖和行級(jí)鎖之間,對(duì)表級(jí)鎖和行級(jí)鎖的折中,并發(fā)度一般。開銷和加鎖時(shí)間也界于表鎖和行鎖之間,會(huì)出現(xiàn)死鎖;

不同的存儲(chǔ)引擎支持不同的鎖機(jī)制:

  • InnoDB存儲(chǔ)引擎支持行級(jí)鎖和表級(jí)鎖,默認(rèn)情況下使用行級(jí)鎖,但只有通過索引進(jìn)行查詢數(shù)據(jù),才使用行級(jí)鎖,否就使用表級(jí)鎖。

  • MyISAM和MEMORY存儲(chǔ)引擎采用的是表級(jí)鎖;

  • BDB存儲(chǔ)引擎使用的是頁面鎖,但也支持表級(jí)鎖;

5.2、InnoDB的行鎖:

InnoDB的行鎖有兩種類型:

  • 共享鎖(S鎖、讀鎖):多個(gè)事務(wù)可以對(duì)同一數(shù)據(jù)行共享一把S鎖,但只能進(jìn)行讀不能修改;

  • 排它鎖(X鎖、寫鎖):一個(gè)事務(wù)獲取排它鎖之后,可以對(duì)鎖定范圍內(nèi)的數(shù)據(jù)行執(zhí)行寫操作,在鎖定期間,其他事務(wù)不能再獲取這部分?jǐn)?shù)據(jù)行的鎖(共享鎖、排它鎖),只允許獲取到排它鎖的事務(wù)進(jìn)行更新數(shù)據(jù)。

對(duì)于update,delete,insert 操作,InnoDB會(huì)自動(dòng)給涉及的數(shù)據(jù)行加排他鎖;對(duì)于普通SELECT語句,InnoDB不會(huì)加任何鎖。

5.3、InnoDB的表鎖與意向鎖:

因?yàn)镮nnoDB引擎允許行鎖和表鎖共存,實(shí)現(xiàn)多粒度的鎖機(jī)制,但是表鎖和行鎖雖然鎖定范圍不同,但是會(huì)相互沖突。當(dāng)你要加表鎖時(shí),勢(shì)必要先遍歷該表的所有記錄,判斷是否有排他鎖。這種遍歷檢查的方式顯然是一種低效的方式,MySQL引入了意向鎖,來檢測(cè)表鎖和行鎖的沖突。

意向鎖也是表級(jí)鎖,分為讀意向鎖(IS鎖)和寫意向鎖(IX鎖)。當(dāng)事務(wù)要在記錄上加上行鎖時(shí),則先在表上加上對(duì)應(yīng)的意向鎖。之后事務(wù)如果想進(jìn)行鎖表,只要先判斷是否有意向鎖存在,存在時(shí)則可快速返回該表不能啟用表鎖,否則就需要等待,提高效率。

5.4、InnoDB行鎖的實(shí)現(xiàn)與臨鍵鎖:

InnoDB的行鎖是通過給索引上的索引項(xiàng)加鎖來實(shí)現(xiàn)的。只有通過索引檢索數(shù)據(jù),才能使用行鎖,否則將使用表鎖。

在InnoDB中,為了解決幻讀的現(xiàn)象,引入了臨鍵鎖(next-key)。根據(jù)索引,劃分為一個(gè)個(gè)左開右閉的區(qū)間。當(dāng)進(jìn)行范圍查詢的時(shí)候,若命中索引且能夠檢索到數(shù)據(jù),則鎖住記錄所在的區(qū)間和它的下一個(gè)區(qū)間。其實(shí),臨鍵鎖(Next-Key) = 記錄鎖(Record Locks) + 間隙鎖(Gap Locks)

  • 間隙鎖:當(dāng)使用范圍查詢而不是精準(zhǔn)查詢進(jìn)行檢索數(shù)據(jù),并請(qǐng)求共享或排它鎖時(shí),InnoDB會(huì)給符合范圍條件的已有數(shù)據(jù)記錄的索引項(xiàng)加鎖;對(duì)于鍵值在條件范圍內(nèi)但并不存在的記錄,叫做間隙(GAP)。

  • 記錄鎖:當(dāng)使用唯一索引,且記錄存在的精準(zhǔn)查詢時(shí),使用記錄鎖

5.5、利用鎖機(jī)制解決并發(fā)問題:

  • X鎖解決臟讀

  • S鎖解決不可重復(fù)讀

  • 臨鍵鎖解決幻讀

InnoDB存儲(chǔ)引擎鎖機(jī)制的詳細(xì)內(nèi)容和MyISAM存儲(chǔ)引擎的鎖機(jī)制的詳細(xì)內(nèi)容可以閱讀這篇文章:MySQL數(shù)據(jù)庫(kù):鎖機(jī)制_張維鵬的博客-CSDN博客_數(shù)據(jù)庫(kù)中的鎖機(jī)制

6、MySQL索引的實(shí)現(xiàn)原理:

索引本質(zhì)上就是一種通過減少查詢需要遍歷行數(shù),加快查詢性能的數(shù)據(jù)結(jié)構(gòu),避免數(shù)據(jù)庫(kù)進(jìn)行全表掃描,好比書的目錄,讓你更快的找到內(nèi)容。(一個(gè)表最多16個(gè)索引)

6.1、索引的優(yōu)缺點(diǎn):

(1)索引的優(yōu)點(diǎn):

  • 減少查詢需要檢索的行數(shù),加快查詢速度,避免進(jìn)行全表掃描,這也是創(chuàng)建索引的最主要的原因。

  • 如果索引的數(shù)據(jù)結(jié)構(gòu)是B+樹,在使用分組和排序時(shí),可以顯著減少查詢中分組和排序的時(shí)間。

  • 通過創(chuàng)建唯一性索引,可以保證數(shù)據(jù)庫(kù)表中每一行數(shù)據(jù)的唯一性。

(2)索引的缺點(diǎn):

  • 當(dāng)對(duì)表中的數(shù)據(jù)進(jìn)行增加、刪除和修改時(shí),索引也要進(jìn)行更新,維護(hù)的耗時(shí)隨著數(shù)據(jù)量的增加而增加。

  • 索引需要占用物理空間,如果要建立聚簇索引,那么需要的空間就會(huì)更大。

6.2、索引的使用場(chǎng)景:

(1)在哪些列上面創(chuàng)建索引:

  • WHERE子句中經(jīng)常出現(xiàn)的列上面創(chuàng)建索引,加快條件的判斷速度。

  • 按范圍存取的列或者在group by或order by中使用的列,因?yàn)樗饕呀?jīng)排序,這樣可以利用索引加快排序查詢時(shí)間。

  • 經(jīng)常用于連接的列上,這些列主要是一些外鍵,可以加快連接的速度;

  • 作為主鍵的列上,強(qiáng)制該列的唯一性和組織表中數(shù)據(jù)的排列結(jié)構(gòu);

(2)不在哪些列建索引?

  • 區(qū)分度不高的列。由于這些列的取值很少,例如性別,在查詢的結(jié)果中,結(jié)果集的數(shù)據(jù)行占了表中數(shù)據(jù)行的很大比例,即需要在表中搜索的數(shù)據(jù)行的比例很大。增加索引,并不能明顯加快檢索速度。

  • 在查詢中很少的列不應(yīng)該創(chuàng)建索引。由于這些列很少使用到,但增加了索引,反而降低了系統(tǒng)的維護(hù)速度和增大了空間需求。

  • 當(dāng)添加索引造成修改成本的提高 遠(yuǎn)遠(yuǎn)大于 檢索性能的提高時(shí),不應(yīng)該創(chuàng)建索引。當(dāng)增加索引時(shí),會(huì)提高檢索性能,但是會(huì)降低修改性能。當(dāng)減少索引時(shí),會(huì)提高修改性能,降低檢索性能。

  • 定義為text, image和bit數(shù)據(jù)類型的列不應(yīng)該增加索引。這些列的數(shù)據(jù)量要么相當(dāng)大,要么取值很少。

6.3、 索引的分類:

(1)普通索引、唯一索引、主鍵索引、全文索引、組合索引。

  • 普通索引:最基本的索引,沒有任何限制

  • 唯一索引:但索引列的值必須唯一,允許有空值,可以有多個(gè)NULL值。如果是組合索引,則列值的組合必須唯一。

  • 主鍵索引:一種特殊的唯一索引,不允許有空值。

  • 全文索引:全文索引僅可用于 MyISAM 表,并只支持從CHAR、VARCHAR或TEXT類型,用于替代效率較低的like 模糊匹配操作,而且可以通過多字段組合的全文索引一次性全模糊匹配多個(gè)字段。

  • 組合索引:主要是為了提高mysql效率,創(chuàng)建組合索引時(shí)應(yīng)該將最常用作限制條件的列放在最左邊,依次遞減。

(2)聚簇索引與非聚簇索引:

如果按數(shù)據(jù)存儲(chǔ)的物理順序與索引值的順序分類,可以將索引分為聚簇索引與非聚簇索引兩類:

  • 聚簇索引:表中數(shù)據(jù)存儲(chǔ)的物理順序與索引值的順序一致,一個(gè)基本表最多只能有一個(gè)聚簇索引,更新聚簇索引列上的數(shù)據(jù)時(shí),往往導(dǎo)致表中記錄的物理順序的變更,代價(jià)較大,因此對(duì)于經(jīng)常更新的列不宜建立聚簇索引

  • 非聚簇索引:表中數(shù)據(jù)的物理順序與索引值的順序不一致的索引組織,一個(gè)基本表可以有多個(gè)聚簇索引。

6.4、索引的數(shù)據(jù)結(jié)構(gòu):

常見的索引的數(shù)據(jù)結(jié)構(gòu)有:B+Tree、Hash索引。

(1)Hash索引:MySQL中只有Memory存儲(chǔ)引擎支持hash索引,是Memory表的默認(rèn)索引類型。hash索引把數(shù)據(jù)以hash值形式組織起來,因此查詢效率非常高,可以一次定位。

hash索引的缺點(diǎn):

  • Hash索引僅能滿足等值的查詢,不能滿足范圍查詢、排序。因?yàn)閿?shù)據(jù)在經(jīng)過Hash算法后,其大小關(guān)系就可能發(fā)生變化。

  • 當(dāng)創(chuàng)建組合索引時(shí),不能只使用組合索引的部分列進(jìn)行查詢。因?yàn)閔ash索引是把多個(gè)列數(shù)據(jù)合并后再計(jì)算Hash值,所以對(duì)單獨(dú)列數(shù)據(jù)計(jì)算Hash值是沒有意義的。

  • 當(dāng)發(fā)生Hash碰撞時(shí),Hash索引不能避免表數(shù)據(jù)的掃描。因?yàn)閮H僅比較Hash值是不夠的,需要比較實(shí)際的值以判定是否符合要求。

(2)B+Tree索引:B+Tree是mysql使用最頻繁的一個(gè)索引數(shù)據(jù)結(jié)構(gòu),是Innodb和Myisam存儲(chǔ)引擎模式的索引類型。B+Tree索引在查找時(shí)需要從根節(jié)點(diǎn)到葉節(jié)點(diǎn)進(jìn)行多次IO操作,在查詢速度比不上Hash索引,但是更適合排序等操作。

B+Tree索引的優(yōu)點(diǎn):

  • 頁內(nèi)節(jié)點(diǎn)不存儲(chǔ)內(nèi)容,每次IO可以讀取更多的行,大大減少磁盤I/O讀取次數(shù)

  • 帶順序訪問指針的B+Tree:B+Tree所有索引數(shù)據(jù)都存儲(chǔ)在葉子結(jié)點(diǎn)上,并且增加了順序訪問指針,每個(gè)葉子節(jié)點(diǎn)都有指向相鄰葉子節(jié)點(diǎn)的指針,這樣做是為了提高區(qū)間查詢效率。

6.5、為什么使用B+Tree作為索引:

索引本身也很大,不可能全部存儲(chǔ)在內(nèi)存中,因此索引往往以索引文件的形式存儲(chǔ)在磁盤上。這樣的話,索引查找過程中就要產(chǎn)生磁盤I/O消耗,相對(duì)于內(nèi)存存取,磁盤I/O存取的消耗要高幾個(gè)數(shù)量級(jí),所以評(píng)價(jià)一個(gè)數(shù)據(jù)結(jié)構(gòu)作為索引的優(yōu)劣最重要的指標(biāo)就是在查找過程中磁盤I/O操作次數(shù)的漸進(jìn)復(fù)雜度。換句話說,索引的數(shù)據(jù)結(jié)構(gòu)要盡量減少查找過程中磁盤I/O的存取次數(shù)。

(1)局部性原理與程序預(yù)讀:

由于磁盤本身存取就比主存慢很多,再加上機(jī)械運(yùn)動(dòng)耗費(fèi),因此為了提高效率,要盡量減少磁盤I/O。為了達(dá)到這個(gè)目的,磁盤往往不是嚴(yán)格按需讀取,而是每次都會(huì)預(yù)讀,即使只需要一個(gè)字節(jié),磁盤也會(huì)從這個(gè)位置開始,順序向后讀取一定長(zhǎng)度的數(shù)據(jù)放入內(nèi)存。這樣做的理論依據(jù)是計(jì)算機(jī)科學(xué)中著名的局部性原理:當(dāng)一個(gè)數(shù)據(jù)被用到時(shí),其附近的數(shù)據(jù)也通常會(huì)馬上被使用。程序運(yùn)行期間所需要的數(shù)據(jù)通常比較集中。

由于磁盤順序讀取的效率很高(不需要尋道時(shí)間,只需很少的旋轉(zhuǎn)時(shí)間),因此對(duì)于具有局部性的程序來說,預(yù)讀可以提高I/O效率。預(yù)讀的長(zhǎng)度一般為頁的整倍數(shù)。當(dāng)程序要讀取的數(shù)據(jù)不在主存中時(shí),會(huì)觸發(fā)一個(gè)缺頁異常,此時(shí)系統(tǒng)會(huì)向磁盤發(fā)出讀盤信號(hào),磁盤會(huì)找到數(shù)據(jù)的起始位置并向后連續(xù)讀取一頁或幾頁載入內(nèi)存中,然后異常返回,程序繼續(xù)運(yùn)行。

(2)B+Tree索引的性能分析:

上文說過一般使用磁盤I/O次數(shù)評(píng)價(jià)索引結(jié)構(gòu)的優(yōu)劣。我們先從B樹分析,B樹檢索一次最多需要訪問h個(gè)節(jié)點(diǎn),同時(shí),數(shù)據(jù)庫(kù)巧妙利用了磁盤預(yù)讀原理,將一個(gè)節(jié)點(diǎn)的大小設(shè)為等于一個(gè)頁,即每次新建節(jié)點(diǎn)時(shí),直接申請(qǐng)一個(gè)頁的空間,這樣就保證一個(gè)節(jié)點(diǎn)在物理上也存儲(chǔ)在一個(gè)頁里,加之計(jì)算機(jī)存儲(chǔ)分配都是按頁對(duì)齊的,這樣就實(shí)現(xiàn)了每個(gè)節(jié)點(diǎn)只需要一次I/O就可以完全載入。B樹中一次檢索最多需要h-1次I/O(根節(jié)點(diǎn)常駐內(nèi)存),時(shí)間復(fù)雜度為O(h)=O(logdN)。一般實(shí)際應(yīng)用中,出度d是非常大的數(shù)字,通常超過100,因此h非常小。綜上所述,用B樹作為索引結(jié)構(gòu)效率是非常高的。

而紅黑樹這種結(jié)構(gòu),雖然時(shí)間復(fù)雜度也為O(h),但是h明顯要深的多,并且由于邏輯上很近的節(jié)點(diǎn),在物理上可能很遠(yuǎn),無法利用局部性,所以IO效率明顯比B樹差很多。

另外,B+Tree更適合作為索引的數(shù)據(jù)結(jié)構(gòu),原因和內(nèi)節(jié)點(diǎn)出度d有關(guān)。從上面分析可以看到,d越大索引的性能越好,而出度d的上限取決于節(jié)點(diǎn)內(nèi)key和data的大小,由于B+Tree內(nèi)節(jié)點(diǎn)去掉了data域,因此可以擁有更大的出度,磁盤IO的次數(shù)也就更少了。

(3)B+樹索引 和 B樹索引 的對(duì)比?

根據(jù)B-Tree 和 B+Tree的結(jié)構(gòu),我們可以發(fā)現(xiàn)B+樹相比于B樹,在文件系統(tǒng)或者數(shù)據(jù)庫(kù)系統(tǒng)當(dāng)中,更有優(yōu)勢(shì),原因如下:

  • (1)B+樹有利于對(duì)數(shù)據(jù)庫(kù)的掃描:B樹在提高了磁盤IO性能的同時(shí)并沒有解決元素遍歷的效率低下的問題,而B+樹只需要遍歷葉子節(jié)點(diǎn)就可以解決對(duì)全部關(guān)鍵字信息的掃描,所以范圍查詢、排序等操作,B+樹有著更高的性能。

  • (2)B+樹的磁盤IO代價(jià)更低:B+樹的內(nèi)部結(jié)點(diǎn)的data域并沒有存儲(chǔ)數(shù)據(jù),因此其內(nèi)部結(jié)點(diǎn)相對(duì)于B樹更小。如果把所有同一內(nèi)部結(jié)點(diǎn)的關(guān)鍵字存放在同一盤塊中,那么盤塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多。一次性讀入內(nèi)存中的需要查找的關(guān)鍵字也就越多,相對(duì)來說I/O讀寫次數(shù)也就降低了。

  • (3)B+樹的查詢效率更加穩(wěn)定:由于B+樹的內(nèi)部結(jié)點(diǎn)只是葉子結(jié)點(diǎn)中關(guān)鍵字的索引,并不存儲(chǔ)數(shù)據(jù)。所以任何關(guān)鍵字的查找必須走一條從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路。所有關(guān)鍵字查詢的路徑長(zhǎng)度相同,導(dǎo)致每一個(gè)數(shù)據(jù)的查詢效率相當(dāng)。

(4)MySQL的 InnoDB 和 MyISAM 存儲(chǔ)引擎中B+Tree索引的實(shí)現(xiàn)?

MyISAM和InnoDB都是使用B+樹索引,MyISAM的主鍵索引和輔助索引的Data域都是保存行的地址,但是InnoDB的主鍵索引保存的不是行的地址,而是保存該行的所有所有數(shù)據(jù),而輔助索引的Data域保存的則是主索引的值。

索引的長(zhǎng)度限制:

  • 對(duì)于 Innodb 的組合索引,如果各個(gè)列中的長(zhǎng)度超過767字節(jié)的,則會(huì)對(duì)超過767字節(jié)的列取前綴索引;對(duì)于 Innodb 的單列索引,如果列的長(zhǎng)度超過767的,則取前綴索引(取前255字符)

  • 對(duì)于 MyISAM 的組合索引,所創(chuàng)建的索引長(zhǎng)度和不能超過1000 bytes,否則會(huì)報(bào)錯(cuò),創(chuàng)建失??;對(duì)于 MyISAM 的單列索引,最大長(zhǎng)度也不能超過1000,否則會(huì)報(bào)警,但是創(chuàng)建成功,最終創(chuàng)建的是前綴索引(取前333個(gè)字符)

7、SQL優(yōu)化和索引優(yōu)化、表結(jié)構(gòu)優(yōu)化:

(1)MySQL的SQL優(yōu)化和索引優(yōu)化:https://blog.csdn.net/a745233700/article/details/84455241

(2)MySQL的表結(jié)構(gòu)優(yōu)化:https://blog.csdn.net/a745233700/article/details/84405087

8、數(shù)據(jù)庫(kù)參數(shù)優(yōu)化:

MySQL屬于 IO 密集型的應(yīng)用程序,主要職責(zé)就是數(shù)據(jù)的管理及存儲(chǔ)工作。而我們知道,從內(nèi)存中讀取一個(gè)數(shù)據(jù)庫(kù)的時(shí)間是微秒級(jí)別,而從一塊普通硬盤上讀取一個(gè)IO是在毫秒級(jí)別,二者相差3個(gè)數(shù)量級(jí)。所以,要優(yōu)化數(shù)據(jù)庫(kù),首先第一步需要優(yōu)化的就是 IO,盡可能將磁盤IO轉(zhuǎn)化為內(nèi)存IO。所以對(duì)于MySQL數(shù)據(jù)庫(kù)的參數(shù)優(yōu)化上,主要針對(duì)減少磁盤IO的參數(shù)做優(yōu)化:比如使用 query_cache_size 調(diào)整查詢緩存的大小,使用 innodb_buffer_pool_size 調(diào)整緩沖區(qū)的大??;

9、explain的執(zhí)行計(jì)劃:

執(zhí)行計(jì)劃是SQL語句經(jīng)過查詢分析器后得到的 抽象語法樹 和 相關(guān)表的統(tǒng)計(jì)信息 作出的一個(gè)查詢方案,這個(gè)方案是由查詢優(yōu)化器自動(dòng)分析產(chǎn)生的。由于是動(dòng)態(tài)數(shù)據(jù)采樣統(tǒng)計(jì)分析出來的結(jié)果,所以可能會(huì)存在分析錯(cuò)誤的情況,也就是存在執(zhí)行計(jì)劃并不是最優(yōu)的情況。通過explain關(guān)鍵字知道MySQL是如何執(zhí)行SQL查詢語句的,分析select 語句的性能瓶頸,從而改進(jìn)我們的查詢,explain的結(jié)果如下:

MySQL數(shù)據(jù)庫(kù)常見面試題有哪些

重要的有id、type、key、key_len、rows、extra:

(1)id:id列可以理解為SQL執(zhí)行順序的標(biāo)識(shí),有幾個(gè)select 就有幾個(gè)id。

  • id值不同:id值越大優(yōu)先級(jí)越高,越先被執(zhí)行;

  • id值相同:從上往下依次執(zhí)行;

  • id列為null:表示這是一個(gè)結(jié)果集,不需要使用它來進(jìn)行查詢。

(2)select_type:查詢的類型,主要用于區(qū)分普通查詢、聯(lián)合查詢、子查詢等復(fù)雜的查詢;

(3)table:表示 explain 的一行正在訪問哪個(gè)表

(4)type:訪問類型,即MySQL決定如何查找表中的行。依次從好到差:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL,除了all之外,其他的 type 類型都可以使用到索引,除了 index_merge 之外,其他的type只可以用到一個(gè)索引。一般要求type為 ref 級(jí)別,范圍查找需要達(dá)到 range 級(jí)別。

  • system:表中只有一條數(shù)據(jù)匹配(等于系統(tǒng)表),可以看成 const 類型的特例

  • const:通過索引一次就找到了,表示使用主鍵索引或者唯一索引

  • eq_ref:主鍵或者唯一索引中的字段被用于連接使用,只會(huì)返回一行匹配的數(shù)據(jù)

  • ref:普通索引掃描,可能返回多個(gè)符合查詢條件的行。

  • fulltext:全文索引檢索,全文索引的優(yōu)先級(jí)很高,若全文索引和普通索引同時(shí)存在時(shí),mysql不管代價(jià),優(yōu)先選擇使用全文索引。

  • ref_or_null:與ref方法類似,只是增加了null值的比較。

  • index_merge:表示查詢使用了兩個(gè)以上的索引,索引合并的優(yōu)化方法,最后取交集或者并集,常見and ,or的條件使用了不同的索引。

  • unique_subquery:用于where中的in形式子查詢,子查詢返回不重復(fù)值唯一值;

  • index_subquery:用于in形式子查詢使用到了輔助索引或者in常數(shù)列表,子查詢可能返回重復(fù)值,可以使用索引將子查詢?nèi)ブ亍?/p>

  • range:索引范圍掃描,常見于使用>,<,between ,in ,like等運(yùn)算符的查詢中。

  • index:索引全表掃描,把索引樹從頭到尾掃描一遍;

  • all:遍歷全表以找到匹配的行(Index與ALL雖然都是讀全表,但index是從索引中讀取,而ALL是從硬盤讀?。?/p>

  • NULL:MySQL在優(yōu)化過程中分解語句,執(zhí)行時(shí)甚至不用訪問表或索引

(5)possible_keys:查詢時(shí)可能使用到的索引

(6)key:實(shí)際使用哪個(gè)索引來優(yōu)化對(duì)該表的訪問

(7)key_len:實(shí)際上用于優(yōu)化查詢的索引長(zhǎng)度,即索引中使用的字節(jié)數(shù)。通過這個(gè)值,可以計(jì)算出一個(gè)多列索引里實(shí)際使用了索引的哪寫字段。

(8)ref:顯示哪個(gè)字段或者常量與key一起被使用

(9)rows:根據(jù)表統(tǒng)計(jì)信息及索引選用情況,大致估算此處查詢需要讀取的行數(shù),不是精確值。

(10)extra:其他的一些額外信息

  • using index:使用覆蓋索引

  • using index condition:查詢的列未被索引覆蓋,where篩選條件使用了索引

  • using temporary:用臨時(shí)表保存中間結(jié)果,常用于 group by 和 order by 操作中,通常是因?yàn)?group by 的列上沒有索引,也有可能是因?yàn)橥瑫r(shí)有g(shù)roup by和order by,但group by和order by的列又不一樣,一般看到它說明查詢需要優(yōu)化了

  • using filesort:MySQL有兩種方式對(duì)查詢結(jié)果進(jìn)行排序,一種是使用索引,另一種是filesort(基于快排實(shí)現(xiàn)的外部排序,性能比較差),當(dāng)數(shù)據(jù)量很大時(shí),這將是一個(gè)CPU密集型的過程,所以可以通過建立合適的索引來優(yōu)化排序的性能

對(duì)explain執(zhí)行計(jì)劃詳請(qǐng)感興趣的讀者可以閱讀這篇文章:https://blog.csdn.net/a745233700/article/details/84335453

10、MySQL的主從復(fù)制:

10.1、MySQL主從復(fù)制的原理:

Slave從Master獲取binlog二進(jìn)制日志文件,然后再將日志文件解析成相應(yīng)的SQL語句在從服務(wù)器上重新執(zhí)行一遍主服務(wù)器的操作,通過這種方式來保證數(shù)據(jù)的一致性。由于主從復(fù)制的過程是異步復(fù)制的,因此Slave和Master之間的數(shù)據(jù)有可能存在延遲的現(xiàn)象,只能保證數(shù)據(jù)最終的一致性。在master和slave之間實(shí)現(xiàn)整個(gè)復(fù)制過程主要由三個(gè)線程來完成:

  • (1)Slave SQL thread線程:創(chuàng)建用于讀取relay log中繼日志并執(zhí)行日志中包含的更新,位于slave端

  • (2)Slave I/O thread線程:讀取 master 服務(wù)器Binlog Dump線程發(fā)送的內(nèi)容并保存到slave服務(wù)器的relay log中繼日志中,位于slave端:

  • (3)Binlog dump thread線程(也稱為IO線程):將bin-log二進(jìn)制日志中的內(nèi)容發(fā)送到slave服務(wù)器,位于master端

注意:如果一臺(tái)主服務(wù)器配兩臺(tái)從服務(wù)器那主服務(wù)器上就會(huì)有兩個(gè)Binlog dump 線程,而每個(gè)從服務(wù)器上各自有兩個(gè)線程;

10.2、主從復(fù)制流程:

  • (1)master服務(wù)器在執(zhí)行SQL語句之后,記錄在binlog二進(jìn)制文件中;

  • (2)slave端的IO線程連接上master端,并請(qǐng)求從指定bin log日志文件的指定pos節(jié)點(diǎn)位置(或者從最開始的日志)開始復(fù)制之后的日志內(nèi)容。

  • (3)master端在接收到來自slave端的IO線程請(qǐng)求后,通知負(fù)責(zé)復(fù)制進(jìn)程的IO線程,根據(jù)slave端IO線程的請(qǐng)求信息,讀取指定binlog日志指定pos節(jié)點(diǎn)位置之后的日志信息,然后返回給slave端的IO線程。該返回信息中除了binlog日志所包含的信息之外,還包括本次返回的信息在master端的binlog文件名以及在該binlog日志中的pos節(jié)點(diǎn)位置。

  • (4)slave端的IO線程在接收到master端IO返回的信息后,將接收到的binlog日志內(nèi)容依次寫入到slave端的relay log文件的最末端,并將讀取到的master端的binlog文件名和pos節(jié)點(diǎn)位置記錄到master-info文件中(該文件存slave端),以便在下一次同步的候能夠告訴master從哪個(gè)位置開始進(jìn)行數(shù)據(jù)同步;

  • (5)slave端的SQL線程在檢測(cè)到relay log文件中新增內(nèi)容后,就馬上解析該relay log文件中的內(nèi)容,然后還原成在master端真實(shí)執(zhí)行的那些SQL語句,再按順序依次執(zhí)行這些SQL語句,從而到達(dá)master端和slave端的數(shù)據(jù)一致性;

10.3、主從復(fù)制的好處:

  • (1)讀寫分離,通過動(dòng)態(tài)增加從服務(wù)器來提高數(shù)據(jù)庫(kù)的性能,在主服務(wù)器上執(zhí)行寫入和更新,在從服務(wù)器上執(zhí)行讀功能。

  • (2)提高數(shù)據(jù)安全,因?yàn)閿?shù)據(jù)已復(fù)制到從服務(wù)器,從服務(wù)器可以終止復(fù)制進(jìn)程,所以,可以在從服務(wù)器上備份而不破壞主服務(wù)器相應(yīng)數(shù)據(jù)。

  • (3)在主服務(wù)器上生成實(shí)時(shí)數(shù)據(jù),而在從服務(wù)器上分析這些數(shù)據(jù),從而提高主服務(wù)器的性能。

10.4、MySQL支持的復(fù)制類型及其優(yōu)缺點(diǎn):

binlog日志文件有兩種格式,一種是Statement-Based(基于語句的復(fù)制),另一種是Row-Based(基于行的復(fù)制)。默認(rèn)格式為Statement-Based,如果想改變其格式在開啟服務(wù)的時(shí)候使用 -binlog-format 選項(xiàng),其具體命令如下:

mysqld_safe –user=msyql –binlog-format=格式 &

(1)基于語句的復(fù)制(Statement-Based):在主服務(wù)器上執(zhí)行的SQL語句,在從服務(wù)器上執(zhí)行同樣的語句。效率比較高。 一旦發(fā)現(xiàn)沒法精確復(fù)制時(shí),會(huì)自動(dòng)選著基于行的復(fù)制。

優(yōu)點(diǎn):

  • ① 因?yàn)橛涗浀腟QL語句,所以占用更少的存儲(chǔ)空間。binlog日志包含了描述數(shù)據(jù)庫(kù)操作的事件,但這些事件包含的情況只是對(duì)數(shù)據(jù)庫(kù)進(jìn)行改變的操作,例如 insert、update、create、delete等操作。相反對(duì)于select、desc等類似的操作并不會(huì)去記錄。

  • ② binlog日志文件記錄了所有的改變數(shù)據(jù)庫(kù)的語句,所以此文件可以作為數(shù)據(jù)庫(kù)的審核依據(jù)。

缺點(diǎn):

  • ① 不安全,不是所有的改變數(shù)據(jù)的語句都會(huì)被記錄。對(duì)于非確定性的行為不會(huì)被記錄。例如:對(duì)于 delete 或者 update 語句,如果使用了 limit 但是并沒有 order by ,這就屬于非確定性的語句,就不會(huì)被記錄。

  • ② 對(duì)于沒有索引條件的update,insert……select 語句,必須鎖定更多的數(shù)據(jù),降低了數(shù)據(jù)庫(kù)的性能。

(2)基于行的復(fù)制(Row-Based):把改變的內(nèi)容復(fù)制過去,而不是把命令在從服務(wù)器上執(zhí)行一遍,從mysql5.0開始支持;

優(yōu)點(diǎn):

  • ① 所有的改變都會(huì)被復(fù)制,這是最安全的復(fù)制方式;

  • ② 對(duì)于 update、insert……select等語句鎖定更少的行;

缺點(diǎn):

  • ① 不能通過binlog日志文件查看什么語句執(zhí)行了,也無從知道在從服務(wù)器上接收到什么語句,我們只能看到什么數(shù)據(jù)改變。

  • ② 因?yàn)橛涗浀氖菙?shù)據(jù),所以說binlog日志文件占用的存儲(chǔ)空間要比Statement-based大。

  • ③ 對(duì)于數(shù)據(jù)量大的操作其花費(fèi)的時(shí)間有更長(zhǎng)。

(3)混合類型的復(fù)制:默認(rèn)采用基于語句的復(fù)制,一旦發(fā)現(xiàn)基于語句的無法精確的復(fù)制時(shí),就會(huì)采用基于行的復(fù)制。

有關(guān)主從復(fù)制更詳細(xì)的內(nèi)容,請(qǐng)閱讀這篇文章:https://blog.csdn.net/a745233700/article/details/85256818

11、讀寫分離:

11.1、實(shí)現(xiàn)原理:

讀寫分離解決的是,數(shù)據(jù)庫(kù)的寫操作,影響了查詢的效率,適用于讀遠(yuǎn)大于寫的場(chǎng)景。讀寫分離的實(shí)現(xiàn)基礎(chǔ)是主從復(fù)制,主數(shù)據(jù)庫(kù)利用主從復(fù)制將自身數(shù)據(jù)的改變同步到從數(shù)據(jù)庫(kù)集群中,然后主數(shù)據(jù)庫(kù)負(fù)責(zé)處理寫操作(當(dāng)然也可以執(zhí)行讀操作),從數(shù)據(jù)庫(kù)負(fù)責(zé)處理讀操作,不能執(zhí)行寫操作。并可以根據(jù)壓力情況,部署多個(gè)從數(shù)據(jù)庫(kù)提高讀操作的速度,減少主數(shù)據(jù)庫(kù)的壓力,提高系統(tǒng)總體的性能。

11.2、讀寫分離提高性能的原因:

  • (1)增加物理服務(wù)器,負(fù)荷分?jǐn)偅?/p>

  • (2)主從只負(fù)責(zé)各自的寫和讀,極大程度的緩解X鎖和S鎖爭(zhēng)用;

  • (3)從庫(kù)可配置MyISAM引擎,提升查詢性能以及節(jié)約系統(tǒng)開銷;

  • (4)主從復(fù)制另外一大功能是增加冗余,提高可用性,當(dāng)一臺(tái)數(shù)據(jù)庫(kù)服務(wù)器宕機(jī)后能通過調(diào)整另外一臺(tái)從庫(kù)來以最快的速度恢復(fù)服務(wù)。

11.3、Mysql讀寫分寫的實(shí)現(xiàn)方式:

  • (1)基于程序代碼內(nèi)部實(shí)現(xiàn):在代碼中根據(jù)select 、insert進(jìn)行路由分類。優(yōu)點(diǎn)是性能較好,因?yàn)槌绦蛟诖a中實(shí)現(xiàn),不需要增加額外的硬件開支,缺點(diǎn)是需要開發(fā)人員來實(shí)現(xiàn),運(yùn)維人員無從下手。

  • (2)基于中間代理層實(shí)現(xiàn):代理一般介于應(yīng)用服務(wù)器和數(shù)據(jù)庫(kù)服務(wù)器之間,代理數(shù)據(jù)庫(kù)服務(wù)器接收到應(yīng)用服務(wù)器的請(qǐng)求后根據(jù)判斷后轉(zhuǎn)發(fā)到后端數(shù)據(jù)庫(kù),有以下代表性的代理層。

12、分庫(kù)分表:垂直分表、垂直分庫(kù)、水平分表、水平分庫(kù)

讀寫分離解決的是數(shù)據(jù)庫(kù)讀寫操作的壓力,但是沒有分散數(shù)據(jù)庫(kù)的存儲(chǔ)壓力,利用分庫(kù)分表可以解決數(shù)據(jù)庫(kù)的儲(chǔ)存瓶頸,并提升數(shù)據(jù)庫(kù)的查詢效率。

12.1、垂直拆分:

(1)垂直分表:將一個(gè)表按照字段分成多個(gè)表,每個(gè)表存儲(chǔ)其中一部分字段。一般會(huì)將常用的字段放到一個(gè)表中,將不常用的字段放到另一個(gè)表中。

優(yōu)點(diǎn):

  • (1)避免IO競(jìng)爭(zhēng)減少鎖表的概率。因?yàn)榇蟮淖侄涡矢停谝?,大字段占用的空間更大,單頁內(nèi)存儲(chǔ)的行數(shù)變少,會(huì)使得IO操作增多;第二數(shù)據(jù)量大,需要的讀取時(shí)間長(zhǎng)。

  • (2)可以更好地提升熱門數(shù)據(jù)的查詢效率。

(2)垂直分庫(kù):按照業(yè)務(wù)模塊的不同,將表拆分到不同的數(shù)據(jù)庫(kù)中,適合業(yè)務(wù)之間的耦合度非常低、業(yè)務(wù)邏輯清晰的系統(tǒng)。

優(yōu)點(diǎn):

  • 降低業(yè)務(wù)中的耦合,方便對(duì)不同的業(yè)務(wù)進(jìn)行分級(jí)管理

  • 可以提升IO、數(shù)據(jù)庫(kù)連接數(shù)、解決單機(jī)硬件存儲(chǔ)資源的瓶頸問題

(3)垂直拆分(分庫(kù)、分表)的缺點(diǎn):

  • 主鍵出現(xiàn)冗余,需要管理冗余列

  • 事務(wù)的處理變得復(fù)雜

  • 仍然存在單表數(shù)據(jù)量過大的問題

12.2、水平拆分:

(1)水平分表:在同一個(gè)數(shù)據(jù)庫(kù)內(nèi),把同一個(gè)表的數(shù)據(jù)按照一定規(guī)則拆分到多個(gè)表中。

優(yōu)點(diǎn):

  • 解決了單表數(shù)據(jù)量過大的問題

  • 避免IO競(jìng)爭(zhēng)并減少鎖表的概率

(2)水平分庫(kù):把同一個(gè)表的數(shù)據(jù)按照一定規(guī)則拆分到不同的數(shù)據(jù)庫(kù)中,不同的數(shù)據(jù)庫(kù)可以放到不同的服務(wù)器上。

優(yōu)點(diǎn):

  • 解決了單庫(kù)大數(shù)據(jù)量的瓶頸問題

  • IO沖突減少,鎖的競(jìng)爭(zhēng)減少,某個(gè)數(shù)據(jù)庫(kù)出現(xiàn)問題不影響其他數(shù)據(jù)庫(kù),提高了系統(tǒng)的穩(wěn)定性和可用性

(3)水平拆分(分表、分庫(kù))的缺點(diǎn):

  • 分片事務(wù)一致性難以解決

  • 跨節(jié)點(diǎn)JOIN性能差,邏輯會(huì)變得復(fù)雜

  • 數(shù)據(jù)擴(kuò)展難度大,不易維護(hù)

12.3、分庫(kù)分表存在的問題的解決:

(1)事務(wù)的問題:

① 方案一:使用分布式事務(wù):

  • 優(yōu)點(diǎn):由數(shù)據(jù)庫(kù)管理,簡(jiǎn)單有效。

  • 缺點(diǎn):性能代價(jià)高,特別是shard越來越多。

② 方案二:程序與數(shù)據(jù)庫(kù)共同控制實(shí)現(xiàn),原理就是將一個(gè)跨多個(gè)數(shù)據(jù)庫(kù)的分布式事務(wù)分解成多個(gè)僅存在于單一數(shù)據(jù)庫(kù)上面的小事務(wù),并交由應(yīng)用程序來總體控制各個(gè)小事務(wù)。

  • 優(yōu)點(diǎn):性能上有優(yōu)勢(shì);

  • 缺點(diǎn):需要在應(yīng)用程序在事務(wù)上做靈活控制。如果使用了spring的事務(wù)管理,改動(dòng)起來會(huì)面臨一定的困難。

(2)跨節(jié)點(diǎn) Join 的問題:

解決該問題的普遍做法是分兩次查詢實(shí)現(xiàn):在第一次查詢的結(jié)果集中找出關(guān)聯(lián)數(shù)據(jù)的id,根據(jù)這些id發(fā)起第二次請(qǐng)求得到關(guān)聯(lián)數(shù)據(jù)。

(3)跨節(jié)點(diǎn)count,order by,group by,分頁和聚合函數(shù)問題:

由于這類問題都需要基于全部數(shù)據(jù)集合進(jìn)行計(jì)算。多數(shù)的代理都不會(huì)自動(dòng)處理合并工作,解決方案:與解決跨節(jié)點(diǎn)join問題的類似,分別在各個(gè)節(jié)點(diǎn)上得到結(jié)果后在應(yīng)用程序端進(jìn)行合并。和 join 不同的是每個(gè)結(jié)點(diǎn)的查詢可以并行執(zhí)行,因此速度要比單一大表快很多。但如果結(jié)果集很大,對(duì)應(yīng)用程序內(nèi)存的消耗是一個(gè)問題。

12.4、分庫(kù)分表后,ID鍵如何處理?

分庫(kù)分表后不能每個(gè)表的ID都是從1開始,所以需要一個(gè)全局ID,設(shè)置全局ID主要有以下幾種方法:

(1)UUID:

  • 優(yōu)點(diǎn):本地生成ID,不需要遠(yuǎn)程調(diào)用,全局唯一不重復(fù)。

  • 缺點(diǎn):占用空間大,不適合作為索引。

(2)數(shù)據(jù)庫(kù)自增ID:在分庫(kù)分表表后使用數(shù)據(jù)庫(kù)自增ID,需要一個(gè)專門用于生成主鍵的庫(kù),每次服務(wù)接收到請(qǐng)求,先向這個(gè)庫(kù)中插入一條沒有意義的數(shù)據(jù),獲取一個(gè)數(shù)據(jù)庫(kù)自增的ID,利用這個(gè)ID去分庫(kù)分表中寫數(shù)據(jù)。

  • 優(yōu)點(diǎn):簡(jiǎn)單易實(shí)現(xiàn)。

  • 缺點(diǎn):在高并發(fā)下存在瓶頸。

(3)Redis生成ID:

  • 優(yōu)點(diǎn):不依賴數(shù)據(jù)庫(kù),性能比較好。

  • 缺點(diǎn):引入新的組件會(huì)使得系統(tǒng)復(fù)雜度增加

(4)Twitter的snowflake算法:是一個(gè)64位的long型的ID,其中有1bit是不用的,41bit作為毫秒數(shù),10bit作為工作機(jī)器ID,12bit作為序列號(hào)。

  • 1bit:第一個(gè)bit默認(rèn)為0,因?yàn)槎M(jìn)制中第一個(gè)bit為1的話為負(fù)數(shù),但是ID不能為負(fù)數(shù).

  • 41bit:表示的是時(shí)間戳,單位是毫秒。

  • 10bit:記錄工作機(jī)器ID,其中5個(gè)bit表示機(jī)房ID,5個(gè)bit表示機(jī)器ID。

  • 12bit:用來記錄同一毫秒內(nèi)產(chǎn)生的不同ID。

(5)美團(tuán)的Leaf分布式ID生成系統(tǒng),美團(tuán)點(diǎn)評(píng)分布式ID生成系統(tǒng):

13、分區(qū):

分區(qū)就是將表的數(shù)據(jù)按照特定規(guī)則存放在不同的區(qū)域,也就是將表的數(shù)據(jù)文件分割成多個(gè)小塊,在查詢數(shù)據(jù)的時(shí)候,只要知道數(shù)據(jù)數(shù)據(jù)存儲(chǔ)在哪些區(qū)域,然后直接在對(duì)應(yīng)的區(qū)域進(jìn)行查詢,不需要對(duì)表數(shù)據(jù)進(jìn)行全部的查詢,提高查詢的性能。同時(shí),如果表數(shù)據(jù)特別大,一個(gè)磁盤磁盤放不下時(shí),我們也可以將數(shù)據(jù)分配到不同的磁盤去,解決存儲(chǔ)瓶頸的問題,利用多個(gè)磁盤,也能夠提高磁盤的IO效率,提高數(shù)據(jù)庫(kù)的性能。在使用分區(qū)表時(shí),需要注意分區(qū)字段必須放在主鍵或者唯一索引中、每個(gè)表最大分區(qū)數(shù)為1024;常見的分區(qū)類型有:Range分區(qū)、List分區(qū)、Hash分區(qū)、Key分區(qū),

  • (1)Range分區(qū):按照連續(xù)的區(qū)間范圍進(jìn)行分區(qū)

  • (2)List分區(qū):按照給定的集合中的值進(jìn)行選擇分區(qū)。

  • (3)Hash分區(qū):基于用戶定義的表達(dá)式的返回值進(jìn)行分區(qū),該表達(dá)式使用將要插入到表中的這些行的列值進(jìn)行計(jì)算。這個(gè)函數(shù)可以包含MySQL中有效的、產(chǎn)生非負(fù)整數(shù)值的任何表達(dá)式。

  • (4)Key分區(qū):類似于按照HASH分區(qū),區(qū)別在于Key分區(qū)只支持計(jì)算一列或多列,且key分區(qū)的哈希函數(shù)是由 MySQL 服務(wù)器提供。

(1)表分區(qū)的優(yōu)點(diǎn):

① 可伸縮性:

  • 將分區(qū)分在不同磁盤,可以解決單磁盤容量瓶頸問題,存儲(chǔ)更多的數(shù)據(jù),也能解決單磁盤的IO瓶頸問題。

② 提升數(shù)據(jù)庫(kù)的性能:

  • 減少數(shù)據(jù)庫(kù)檢索時(shí)需要遍歷的數(shù)據(jù)量,在查詢時(shí)只需要在數(shù)據(jù)對(duì)應(yīng)的分區(qū)進(jìn)行查詢。

  • 避免Innodb的單個(gè)索引的互斥訪問限制

  • 對(duì)于聚合函數(shù),例如sum()和count(),可以在每個(gè)分區(qū)進(jìn)行并行處理,最終只需要統(tǒng)計(jì)所有分區(qū)得到的結(jié)果

③ 方便對(duì)數(shù)據(jù)進(jìn)行運(yùn)維管理:

  • 方便管理,對(duì)于失去保存意義的數(shù)據(jù),通過刪除對(duì)應(yīng)的分區(qū),達(dá)到快速刪除的作用。比如刪除某一時(shí)間的歷史數(shù)據(jù),直接執(zhí)行truncate,或者直接drop整個(gè)分區(qū),這比detele刪除效率更高;

  • 在某些場(chǎng)景下,單個(gè)分區(qū)表的備份很恢復(fù)會(huì)更有效率。

14、主鍵一般用自增ID還是UUID?

(1)自增ID:

使用自增ID的好處:

  • 字段長(zhǎng)度較 UUID 會(huì)小很多。

  • 數(shù)據(jù)庫(kù)自動(dòng)編號(hào),按順序存放,利于檢索

  • 無需擔(dān)心主鍵重復(fù)問題

使用自增ID的缺點(diǎn):

  • 因?yàn)槭亲栽?,在某些業(yè)務(wù)場(chǎng)景下,容易被其他人查到業(yè)務(wù)量。

  • 發(fā)生數(shù)據(jù)遷移時(shí),或者表合并時(shí)會(huì)非常麻煩

  • 在高并發(fā)的場(chǎng)景下,競(jìng)爭(zhēng)自增鎖會(huì)降低數(shù)據(jù)庫(kù)的吞吐能力

(2)UUID:通用唯一標(biāo)識(shí)碼,UUID是基于當(dāng)前時(shí)間、計(jì)數(shù)器和硬件標(biāo)識(shí)等數(shù)據(jù)計(jì)算生成的。

使用UUID的優(yōu)點(diǎn):

  • 唯一標(biāo)識(shí),不用考慮重復(fù)問題,在數(shù)據(jù)拆分、合并時(shí)也能達(dá)到全局的唯一性。

  • 可以在應(yīng)用層生成,提高數(shù)據(jù)庫(kù)的吞吐能力。

  • 無需擔(dān)心業(yè)務(wù)量泄露的問題。

使用UUID的缺點(diǎn):

  • 因?yàn)閁UID是隨機(jī)生成的,所以會(huì)發(fā)生隨機(jī)IO,影響插入速度,并且會(huì)造成硬盤的使用率較低。

  • UUID占用空間較大,建立的索引越多,造成的影響越大。

  • UUID之間比較大小較自增ID慢不少,影響查詢速度。

一般情況下,MySQL推薦使用自增ID,因?yàn)樵贛ySQL的 InnoDB 存儲(chǔ)引擎中,主鍵索引是聚簇索引,主鍵索引的B+樹的葉子節(jié)點(diǎn)按照順序存儲(chǔ)了主鍵值及數(shù)據(jù),如果主鍵索引是自增ID,只需要按順序往后排列即可,如果是UUID,ID是隨機(jī)生成的,在數(shù)據(jù)插入時(shí)會(huì)造成大量的數(shù)據(jù)移動(dòng),產(chǎn)生大量的內(nèi)存碎片,造成插入性能的下降。

15、視圖View:

視圖是從一個(gè)或者多個(gè)表(或視圖)導(dǎo)出的表,其內(nèi)容由查詢定義。視圖是一個(gè)虛擬表,數(shù)據(jù)庫(kù)中只存儲(chǔ)視圖的定義,不存儲(chǔ)視圖對(duì)應(yīng)的數(shù)據(jù),在對(duì)視圖的數(shù)據(jù)進(jìn)行操作時(shí),系統(tǒng)根據(jù)視圖的定義去操作相應(yīng)的基本表??梢哉f,視圖是在基本表之上建立的表,它的結(jié)構(gòu)和內(nèi)容都來自基本表,依據(jù)基本表存在而存在。一個(gè)視圖可以對(duì)應(yīng)一個(gè)基本表,也可以對(duì)應(yīng)多個(gè)基本表。視圖是基本表的抽象和在邏輯意義上建立的新關(guān)系。

(1)視圖的優(yōu)點(diǎn):

  • 簡(jiǎn)化了操作,把經(jīng)常使用的數(shù)據(jù)定義為視圖

  • 安全性,用戶只能查詢和修改能看到的數(shù)據(jù)

  • 邏輯上的獨(dú)立性,屏蔽了真實(shí)表的結(jié)構(gòu)帶來的影響

(2)視圖的缺點(diǎn):

  • 性能差,數(shù)據(jù)庫(kù)必須把對(duì)視圖的查詢轉(zhuǎn)化成對(duì)基本表的查詢,如果這個(gè)視圖是由一個(gè)復(fù)雜的多表查詢所定義,那么,即使是視圖的一個(gè)簡(jiǎn)單查詢,數(shù)據(jù)庫(kù)也要把它變成一個(gè)復(fù)雜的結(jié)合體,需要花費(fèi)一定的時(shí)間。

16、存儲(chǔ)過程Procedure:

SQL語句需要先編譯然后執(zhí)行,而存儲(chǔ)過程就是一組為了完成特定功能的SQL語句集,經(jīng)過編譯后存儲(chǔ)在數(shù)據(jù)庫(kù)中,用戶通過制定存儲(chǔ)過程的名字并給定參數(shù)來調(diào)用它。

用程序也可以實(shí)現(xiàn)操作數(shù)據(jù)庫(kù)的復(fù)雜邏輯,那為什么需要存儲(chǔ)過程呢?主要是因?yàn)槭褂贸绦蛘{(diào)用API執(zhí)行,其效率相對(duì)較慢,應(yīng)用程序需通過引擎把SQL語句交給MYSQL引擎來執(zhí)行,那還不如直接讓MySQL負(fù)責(zé)它最精通最能夠完成的工作。

存儲(chǔ)過程的優(yōu)點(diǎn):

  • (1)標(biāo)準(zhǔn)組件式編程:存儲(chǔ)過程創(chuàng)建后,可以在程序中被多次調(diào)用,而不必重新編寫該存儲(chǔ)過程的SQL語句。并且DBA可以隨時(shí)對(duì)存儲(chǔ)過程進(jìn)行修改,對(duì)應(yīng)用程序源代碼毫無影響。

  • (2)更快的執(zhí)行速度:如果某一操作包含大量的Transaction-SQL代碼或分別被多次執(zhí)行,那么存儲(chǔ)過程要比批處理的執(zhí)行速度快很多。因?yàn)榇鎯?chǔ)過程是預(yù)編譯的,在首次運(yùn)行一個(gè)存儲(chǔ)過程時(shí)查詢,優(yōu)化器對(duì)其進(jìn)行分析優(yōu)化,并且給出最終被存儲(chǔ)在系統(tǒng)表中的執(zhí)行計(jì)劃。而批處理的Transaction-SQL語句在每次運(yùn)行時(shí)都要進(jìn)行編譯和優(yōu)化,速度相對(duì)要慢一些。

  • (3)增強(qiáng)SQL語言的功能和靈活性:存儲(chǔ)過程可以用控制語句編寫,有很強(qiáng)的靈活性,可以完成復(fù)雜的判雜的斷和較復(fù)運(yùn)算。

  • (4)減少網(wǎng)絡(luò)流量:針對(duì)同一個(gè)數(shù)據(jù)庫(kù)對(duì)象的操作(如查詢、修改),如果這一操作所涉及的Transaction-SQL語句被組織進(jìn)存儲(chǔ)過程,那么當(dāng)在客戶計(jì)算機(jī)上調(diào)用該存儲(chǔ)過程時(shí),網(wǎng)絡(luò)中傳送的只是該調(diào)用語句,從而大大減少網(wǎng)絡(luò)流量并降低了網(wǎng)絡(luò)負(fù)載。

  • (5)作為一種安全機(jī)制來充分利用:通過對(duì)執(zhí)行某一存儲(chǔ)過程的權(quán)限進(jìn)行限制,能夠?qū)崿F(xiàn)對(duì)相應(yīng)的數(shù)據(jù)的訪問權(quán)限的限制,避免了非授權(quán)用戶對(duì)數(shù)據(jù)的訪問,保證了數(shù)據(jù)的安全。

17、觸發(fā)器Trigger:

觸發(fā)器是與表有關(guān)的數(shù)據(jù)庫(kù)對(duì)象,當(dāng)觸發(fā)器所在表上出現(xiàn)指定事件并滿足定義條件的時(shí)候,將執(zhí)行觸發(fā)器中定義的語句集合。觸發(fā)器的特性可以應(yīng)用在數(shù)據(jù)庫(kù)端確保數(shù)據(jù)的完整性。觸發(fā)器是一個(gè)特殊的存儲(chǔ)過程,不同的是存儲(chǔ)過程要用call來調(diào)用,而觸發(fā)器不需要使用call,也不需要手工調(diào)用,它在插入,刪除或修改特定表中的數(shù)據(jù)時(shí)觸發(fā)執(zhí)行,它比數(shù)據(jù)庫(kù)本身標(biāo)準(zhǔn)的功能有更精細(xì)和更復(fù)雜的數(shù)據(jù)控制能力。

18、游標(biāo)Cursor:

游標(biāo),就是游動(dòng)的標(biāo)識(shí),可以充當(dāng)指針的作用,使用游標(biāo)可以遍歷查詢數(shù)據(jù)庫(kù)返回的結(jié)果集中的所有記錄,但是每次只能提取一條記錄,即每次只能指向并取出一行的數(shù)據(jù),以便進(jìn)行相應(yīng)的操作。當(dāng)你沒有使用游標(biāo)的時(shí)候,相當(dāng)于別人一下給你所有的東西讓你拿走;用了游標(biāo)之后,相當(dāng)于別人一件一件的給你,這時(shí)你可以先看看這個(gè)東西好不好,再自己進(jìn)行選擇。

到此,相信大家對(duì)“MySQL數(shù)據(jù)庫(kù)常見面試題有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

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

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

AI