新聞中心
「春招系列」MySQL面試核心25問(附答案)
篇幅所限本文只寫了MySQL25題,像其他的Redis,SSM框架,算法,計(jì)網(wǎng)等技術(shù)棧的面試題后面會(huì)持續(xù)更新,個(gè)人整理的1000余道面試八股文會(huì)放在文末給大家白嫖,最近有面試需要刷題的同學(xué)可以直接翻到文末領(lǐng)取。
創(chuàng)新互聯(lián)建站提供高防物理服務(wù)器租用、云服務(wù)器、香港服務(wù)器、服務(wù)器托管德陽等
如果表使用自增主鍵,那么每次插入新的記錄,記錄就會(huì)順序添加到當(dāng)前索引節(jié)點(diǎn)的后續(xù)位置,當(dāng)一頁寫滿,就會(huì)自動(dòng)開辟一個(gè)新的頁。如果使用非自增主鍵(如果身份證號(hào)或?qū)W號(hào)等),由于每次插入主鍵的值近似于隨機(jī),因此每次新紀(jì)錄都要被插到現(xiàn)有索引頁得中間某個(gè)位置, 頻繁的移動(dòng)、分頁操作造成了大量的碎片,得到了不夠緊湊的索引結(jié)構(gòu),后續(xù)不得不通過OPTIMIZE TABLE(optimize table)來重建表并優(yōu)化填充頁面。
Server層按順序執(zhí)行sql的步驟為:
簡(jiǎn)單概括:
可以分為服務(wù)層和存儲(chǔ)引擎層兩部分,其中:
服務(wù)層包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等 ,涵蓋MySQL的大多數(shù)核心服務(wù)功能,以及所有的內(nèi)置函數(shù)(如日期、時(shí)間、數(shù)學(xué)和加密函數(shù)等),所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn),比如存儲(chǔ)過程、觸發(fā)器、視圖等。
存儲(chǔ)引擎層負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和提取 。其架構(gòu)模式是插件式的,支持InnoDB、MyISAM、Memory等多個(gè)存儲(chǔ)引擎?,F(xiàn)在最常用的存儲(chǔ)引擎是InnoDB,它從MySQL 5.5.5版本開始成為了默認(rèn)的存儲(chǔ)引擎。
Drop、Delete、Truncate都表示刪除,但是三者有一些差別:
Delete 用來刪除表的全部或者一部分?jǐn)?shù)據(jù)行,執(zhí)行Delete之后,用戶需要提交(commmit)或者回滾(rollback)來執(zhí)行刪除或者撤銷刪除,會(huì)觸發(fā)這個(gè)表上所有的delete觸發(fā)器。
Truncate 刪除表中的所有數(shù)據(jù),這個(gè)操作不能回滾,也不會(huì)觸發(fā)這個(gè)表上的觸發(fā)器,TRUNCATE比Delete更快,占用的空間更小。
Drop 命令從數(shù)據(jù)庫中刪除表,所有的數(shù)據(jù)行,索引和權(quán)限也會(huì)被刪除,所有的DML觸發(fā)器也不會(huì)被觸發(fā),這個(gè)命令也不能回滾。
因此,在不再需要一張表的時(shí)候,用Drop;在想刪除部分?jǐn)?shù)據(jù)行時(shí)候,用Delete;在保留表而刪除所有數(shù)據(jù)的時(shí)候用Truncate。
隔離級(jí)別臟讀不可重復(fù)讀幻影讀 READ-UNCOMMITTED 未提交讀 READ-COMMITTED 提交讀 REPEATABLE-READ 重復(fù)讀 SERIALIZABLE 可串行化讀
MySQL InnoDB 存儲(chǔ)引擎的默認(rèn)支持的隔離級(jí)別是 REPEATABLE-READ (可重讀)
這里需要注意的是 :與 SQL 標(biāo)準(zhǔn)不同的地方在于InnoDB 存儲(chǔ)引擎在 REPEATABLE-READ(可重讀)事務(wù)隔離級(jí)別 下使用的是 Next-Key Lock 鎖 算法,因此可以避免幻讀的產(chǎn)生,這與其他數(shù)據(jù)庫系統(tǒng)(如 SQL Server)是不同的。所以 說InnoDB 存儲(chǔ)引擎的默認(rèn)支持的隔離級(jí)別是 REPEATABLE-READ(可重讀) 已經(jīng)可以完全保證事務(wù)的隔離性要 求,即達(dá)到了 SQL標(biāo)準(zhǔn)的SERIALIZABLE(可串行化)隔離級(jí)別。
因?yàn)楦綦x級(jí)別越低,事務(wù)請(qǐng)求的鎖越少,所以大部分?jǐn)?shù)據(jù)庫系統(tǒng)的隔離級(jí)別都是READ-COMMITTED(讀取提交內(nèi) 容):,但是你要知道的是InnoDB 存儲(chǔ)引擎默認(rèn)使用 REPEATABLE-READ(可重讀)并不會(huì)有任何性能損失 。
InnoDB 存儲(chǔ)引擎在分布式事務(wù) 的情況下一般會(huì)用到SERIALIZABLE(可串行化)隔離級(jí)別。
主要原因:B+樹只要遍歷葉子節(jié)點(diǎn)就可以實(shí)現(xiàn)整棵樹的遍歷,而且在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節(jié)點(diǎn),效率太低。
文件與數(shù)據(jù)庫都是需要較大的存儲(chǔ),也就是說,它們都不可能全部存儲(chǔ)在內(nèi)存中,故需要存儲(chǔ)到磁盤上。而所謂索引,則為了數(shù)據(jù)的快速定位與查找,那么索引的結(jié)構(gòu)組織要盡量減少查找過程中磁盤I/O的存取次數(shù),因此B+樹相比B樹更為合適。數(shù)據(jù)庫系統(tǒng)巧妙利用了局部性原理與磁盤預(yù)讀原理,將一個(gè)節(jié)點(diǎn)的大小設(shè)為等于一個(gè)頁,這樣每個(gè)節(jié)點(diǎn)只需要一次I/O就可以完全載入,而紅黑樹這種結(jié)構(gòu),高度明顯要深的多,并且由于邏輯上很近的節(jié)點(diǎn)(父子)物理上可能很遠(yuǎn),無法利用局部性。
最重要的是,B+樹還有一個(gè)最大的好處:方便掃庫。
B樹必須用中序遍歷的方法按序掃庫,而B+樹直接從葉子結(jié)點(diǎn)挨個(gè)掃一遍就完了,B+樹支持range-query非常方便,而B樹不支持,這是數(shù)據(jù)庫選用B+樹的最主要原因。
B+樹查找效率更加穩(wěn)定,B樹有可能在中間節(jié)點(diǎn)找到數(shù)據(jù),穩(wěn)定性不夠。
B+tree的磁盤讀寫代價(jià)更低:B+tree的內(nèi)部結(jié)點(diǎn)并沒有指向關(guān)鍵字具體信息的指針(紅色部分),因此其內(nèi)部結(jié)點(diǎn)相對(duì)B 樹更小。如果把所有同一內(nèi)部結(jié)點(diǎn)的關(guān)鍵字存放在同一塊盤中,那么盤塊所能容納的關(guān)鍵字?jǐn)?shù)量也越多。一次性讀入內(nèi)存中的需要查找的關(guān)鍵字也就越多,相對(duì)來說IO讀寫次數(shù)也就降低了;
B+tree的查詢效率更加穩(wěn)定:由于內(nèi)部結(jié)點(diǎn)并不是最終指向文件內(nèi)容的結(jié)點(diǎn),而只是葉子結(jié)點(diǎn)中關(guān)鍵字的索引,所以,任何關(guān)鍵字的查找必須走一條從根結(jié)點(diǎn)到葉子結(jié)點(diǎn)的路。所有關(guān)鍵字查詢的路徑長度相同,導(dǎo)致每一個(gè)數(shù)據(jù)的查詢效率相當(dāng);
視圖是一種虛擬的表,通常是有一個(gè)表或者多個(gè)表的行或列的子集,具有和物理表相同的功能 游標(biāo)是對(duì)查詢出來的結(jié)果集作為一個(gè)單元來有效的處理。一般不使用游標(biāo),但是需要逐條處理數(shù)據(jù)的時(shí)候,游標(biāo)顯得十分重要。
而在 MySQL 中,恢復(fù)機(jī)制是通過回滾日志(undo log)實(shí)現(xiàn)的,所有事務(wù)進(jìn)行的修改都會(huì)先記錄到這個(gè)回滾日志中,然后在對(duì)數(shù)據(jù)庫中的對(duì)應(yīng)行進(jìn)行寫入。當(dāng)事務(wù)已經(jīng)被提交之后,就無法再次回滾了。
回滾日志作用:1)能夠在發(fā)生錯(cuò)誤或者用戶執(zhí)行 ROLLBACK 時(shí)提供回滾相關(guān)的信息 2) 在整個(gè)系統(tǒng)發(fā)生崩潰、數(shù)據(jù)庫進(jìn)程直接被殺死后,當(dāng)用戶再次啟動(dòng)數(shù)據(jù)庫進(jìn)程時(shí),還能夠立刻通過查詢回滾日志將之前未完成的事務(wù)進(jìn)行回滾,這也就需要回滾日志必須先于數(shù)據(jù)持久化到磁盤上,是我們需要先寫日志后寫數(shù)據(jù)庫的主要原因。
InnoDB
MyISAM
總結(jié)
數(shù)據(jù)庫并發(fā)會(huì)帶來臟讀、幻讀、丟棄更改、不可重復(fù)讀這四個(gè)常見問題,其中:
臟讀 :在第一個(gè)修改事務(wù)和讀取事務(wù)進(jìn)行的時(shí)候,讀取事務(wù)讀到的數(shù)據(jù)為100,這是修改之后的數(shù)據(jù),但是之后該事務(wù)滿足一致性等特性而做了回滾操作,那么讀取事務(wù)得到的結(jié)果就是臟數(shù)據(jù)了。
幻讀 :一般是T1在某個(gè)范圍內(nèi)進(jìn)行修改操作(增加或者刪除),而T2讀取該范圍導(dǎo)致讀到的數(shù)據(jù)是修改之間的了,強(qiáng)調(diào)范圍。
丟棄修改 :兩個(gè)寫事務(wù)T1 T2同時(shí)對(duì)A=0進(jìn)行遞增操作,結(jié)果T2覆蓋T1,導(dǎo)致最終結(jié)果是1 而不是2,事務(wù)被覆蓋
不可重復(fù)讀 :T2 讀取一個(gè)數(shù)據(jù),然后T1 對(duì)該數(shù)據(jù)做了修改。如果 T2 再次讀取這個(gè)數(shù)據(jù),此時(shí)讀取的結(jié)果和第一次讀取的結(jié)果不同。
第一個(gè)事務(wù)首先讀取var變量為50,接著準(zhǔn)備更新為100的時(shí),并未提交,第二個(gè)事務(wù)已經(jīng)讀取var為100,此時(shí)第一個(gè)事務(wù)做了回滾。最終第二個(gè)事務(wù)讀取的var和數(shù)據(jù)庫的var不一樣。
T1 讀取某個(gè)范圍的數(shù)據(jù),T2 在這個(gè)范圍內(nèi)插入新的數(shù)據(jù),T1 再次讀取這個(gè)范圍的數(shù)據(jù),此時(shí)讀取的結(jié)果和和第一次讀取的結(jié)果不同。
T1 和 T2 兩個(gè)事務(wù)都對(duì)一個(gè)數(shù)據(jù)進(jìn)行修改,T1 先修改,T2 隨后修改,T2 的修改覆蓋了 T1 的修改。例如:事務(wù)1讀取某表中的數(shù)據(jù)A=50,事務(wù)2也讀取A=50,事務(wù)1修改A=A+50,事務(wù)2也修改A=A+50,最終結(jié)果A=100,事務(wù)1的修改被丟失。
T2 讀取一個(gè)數(shù)據(jù),T1 對(duì)該數(shù)據(jù)做了修改。如果 T2 再次讀取這個(gè)數(shù)據(jù),此時(shí)讀取的結(jié)果和第一次讀取的結(jié)果不同。
悲觀鎖,先獲取鎖,再進(jìn)行業(yè)務(wù)操作,一般就是利用類似 SELECT … FOR UPDATE 這樣的語句,對(duì)數(shù)據(jù)加鎖,避免其他事務(wù)意外修改數(shù)據(jù)。當(dāng)數(shù)據(jù)庫執(zhí)行SELECT … FOR UPDATE時(shí)會(huì)獲取被select中的數(shù)據(jù)行的行鎖,select for update獲取的行鎖會(huì)在當(dāng)前事務(wù)結(jié)束時(shí)自動(dòng)釋放,因此必須在事務(wù)中使用。
樂觀鎖,先進(jìn)行業(yè)務(wù)操作,只在最后實(shí)際更新數(shù)據(jù)時(shí)進(jìn)行檢查數(shù)據(jù)是否被更新過。Java 并發(fā)包中的 AtomicFieldUpdater 類似,也是利用 CAS 機(jī)制,并不會(huì)對(duì)數(shù)據(jù)加鎖,而是通過對(duì)比數(shù)據(jù)的時(shí)間戳或者版本號(hào),來實(shí)現(xiàn)樂觀鎖需要的版本判斷。
分庫與分表的目的在于,減小數(shù)據(jù)庫的單庫單表負(fù)擔(dān),提高查詢性能,縮短查詢時(shí)間。
通過分表 ,可以減少數(shù)據(jù)庫的單表負(fù)擔(dān),將壓力分散到不同的表上,同時(shí)因?yàn)椴煌谋砩系臄?shù)據(jù)量少了,起到提高查詢性能,縮短查詢時(shí)間的作用,此外,可以很大的緩解表鎖的問題。分表策略可以歸納為垂直拆分和水平拆分:
水平分表 :取模分表就屬于隨機(jī)分表,而時(shí)間維度分表則屬于連續(xù)分表。如何設(shè)計(jì)好垂直拆分,我的建議:將不常用的字段單獨(dú)拆分到另外一張擴(kuò)展表. 將大文本的字段單獨(dú)拆分到另外一張擴(kuò)展表, 將不經(jīng)常修改的字段放在同一張表中,將經(jīng)常改變的字段放在另一張表中。對(duì)于海量用戶場(chǎng)景,可以考慮取模分表,數(shù)據(jù)相對(duì)比較均勻,不容易出現(xiàn)熱點(diǎn)和并發(fā)訪問的瓶頸。
庫內(nèi)分表 ,僅僅是解決了單表數(shù)據(jù)過大的問題,但并沒有把單表的數(shù)據(jù)分散到不同的物理機(jī)上,因此并不能減輕 MySQL 服務(wù)器的壓力,仍然存在同一個(gè)物理機(jī)上的資源競(jìng)爭(zhēng)和瓶頸,包括 CPU、內(nèi)存、磁盤 IO、網(wǎng)絡(luò)帶寬等。
分庫與分表帶來的分布式困境與應(yīng)對(duì)之策 數(shù)據(jù)遷移與擴(kuò)容問題----一般做法是通過程序先讀出數(shù)據(jù),然后按照指定的分表策略再將數(shù)據(jù)寫入到各個(gè)分表中。分頁與排序問題----需要在不同的分表中將數(shù)據(jù)進(jìn)行排序并返回,并將不同分表返回的結(jié)果集進(jìn)行匯總和再次排序,最后再返回給用戶。
不可重復(fù)讀的重點(diǎn)是修改,幻讀的重點(diǎn)在于新增或者刪除。
視圖是虛擬的表,與包含數(shù)據(jù)的表不一樣,視圖只包含使用時(shí)動(dòng)態(tài)檢索數(shù)據(jù)的查詢;不包含任何列或數(shù)據(jù)。使用視圖可以簡(jiǎn)化復(fù)雜的 sql 操作,隱藏具體的細(xì)節(jié),保護(hù)數(shù)據(jù);視圖創(chuàng)建后,可以使用與表相同的方式利用它們。
視圖不能被索引,也不能有關(guān)聯(lián)的觸發(fā)器或默認(rèn)值,如果視圖本身內(nèi)有order by 則對(duì)視圖再次order by將被覆蓋。
創(chuàng)建視圖:create view xxx as xxxx
對(duì)于某些視圖比如未使用聯(lián)結(jié)子查詢分組聚集函數(shù)Distinct Union等,是可以對(duì)其更新的,對(duì)視圖的更新將對(duì)基表進(jìn)行更新;但是視圖主要用于簡(jiǎn)化檢索,保護(hù)數(shù)據(jù),并不用于更新,而且大部分視圖都不可以更新。
B+tree的磁盤讀寫代價(jià)更低,B+tree的查詢效率更加穩(wěn)定 數(shù)據(jù)庫索引采用B+樹而不是B樹的主要原因:B+樹只要遍歷葉子節(jié)點(diǎn)就可以實(shí)現(xiàn)整棵樹的遍歷,而且在數(shù)據(jù)庫中基于范圍的查詢是非常頻繁的,而B樹只能中序遍歷所有節(jié)點(diǎn),效率太低。
B+樹的特點(diǎn)
在最頻繁使用的、用以縮小查詢范圍的字段,需要排序的字段上建立索引。不宜:1)對(duì)于查詢中很少涉及的列或者重復(fù)值比較多的列 2)對(duì)于一些特殊的數(shù)據(jù)類型,不宜建立索引,比如文本字段(text)等。
如果一個(gè)索引包含(或者說覆蓋)所有需要查詢的字段的值,我們就稱 之為“覆蓋索引”。
我們知道在InnoDB存儲(chǔ)引 擎中,如果不是主鍵索引,葉子節(jié)點(diǎn)存儲(chǔ)的是主鍵+列值。最終還是要“回表”,也就是要通過主鍵再查找一次,這樣就 會(huì)比較慢。覆蓋索引就是把要查詢出的列和索引是對(duì)應(yīng)的,不做回表操作!
舉例 :
學(xué)號(hào)姓名性別年齡系別專業(yè) 20020612李輝男20計(jì)算機(jī)軟件開發(fā) 20060613張明男18計(jì)算機(jī)軟件開發(fā) 20060614王小玉女19物理力學(xué) 20060615李淑華女17生物動(dòng)物學(xué) 20060616趙靜男21化學(xué)食品化學(xué) 20060617趙靜女20生物植物學(xué)
主鍵為候選鍵的子集,候選鍵為超鍵的子集,而外鍵的確定是相對(duì)于主鍵的。
汗顏!工作10年去面試,被“MySQL怎么保證事物一致性”難倒了
阿牛去一家中意的公司面試,本以為憑借以往豐富的經(jīng)驗(yàn),肯定手到擒來,結(jié)果第一個(gè)問題,我就“出門右拐”了。
問題就是:MySQL是怎么保證事務(wù)一致性的?
回到家阿牛翻閱資料,終于搞懂了,在這里分享給大家。
定義
在搞清楚問題答案之前,先搞清楚以下幾個(gè)名詞以及大致的用處
redo log:
通常是物理日志,記錄的是數(shù)據(jù)頁的物理修改,而不是某一行或某幾行修改成怎樣怎樣,它用來恢復(fù)提交后的物理數(shù)據(jù)頁(恢復(fù)數(shù)據(jù)頁,且只能恢復(fù)到最后一次提交的位置)、Innodb特有的,他在存儲(chǔ)引擎層。循環(huán)寫的,空間固定會(huì)用完。作用是crash-safe能力
binlog:
是邏輯日志,記錄的是這個(gè)語句的原始邏輯,比如“給 ID=2 這一行的 c 字段加 1 ” 是 MySQL 的 Server 層實(shí)現(xiàn)的,所有引擎都可以使用。是可以追加寫入的,“追加寫”是指 binlog 文件寫到一定大小后會(huì)切換到下一個(gè),并不會(huì)覆蓋以前的日志。作用是數(shù)據(jù)歸檔
undo log:
有兩個(gè)作用:提供回滾和多個(gè)行版本控制(MVCC)。
在數(shù)據(jù)修改的時(shí)候,不僅記錄了redo,還記錄了相對(duì)應(yīng)的undo,如果因?yàn)槟承┰驅(qū)е率聞?wù)失敗或回滾了,可以借助該undo進(jìn)行回滾。
SQL執(zhí)行的過程
了解了以上名詞之后,讓我們看一下“一條更新SQL語句執(zhí)行的過程是什么?”
如圖1有幾個(gè)關(guān)鍵步驟:
1、先查找記錄所在的Innodb頁在不在內(nèi)存里;如果不在內(nèi)存里則將記錄所在的頁加載在內(nèi)存里;根據(jù)SQL語句在內(nèi)存中將記錄更新
2、將更新前的記錄寫入undolog
3、根據(jù)記錄的更新值將變更寫入redolog(buffer)中,并將狀態(tài)變更為prepare
4、將變更記錄到邏輯日志
5、redolog日志中的狀態(tài)修改為commit,返回結(jié)束
至此:一條更新語句的過程結(jié)束
上面的步驟中有些同學(xué)可能會(huì)有一些疑問:為什么更新一條記錄要把一整頁數(shù)據(jù)加載到內(nèi)存里答:因?yàn)镮nnodb引擎中,最小的存儲(chǔ)單位是頁為什么一定要加載到內(nèi)存里?答:因?yàn)樗械挠?jì)算操作都是在內(nèi)存里,操作完成后最終才寫回磁盤為什么要寫入redolog,直接寫入磁盤,然后寫入binlog就好了?。看穑哼@將在下面會(huì)提到,請(qǐng)往后看
為了加深理解,準(zhǔn)備了下面2張圖輔助理解
以圖3為例,讓我們看看在每個(gè)步驟出現(xiàn)異常的時(shí)候,到底怎么保證事物一致性的吧!1、步驟123,所有的操作最多還只是內(nèi)存里,如果出現(xiàn)宕機(jī)、斷電等異常,? 記錄不會(huì)有任何變動(dòng),事物是一致的2、步驟4剛執(zhí)行完,斷電了,因?yàn)閞edolog還處在prepare狀態(tài),???這時(shí)候事物也是一致的3、步驟5記錄binlog的過程中斷電了,這時(shí)候要保證主從一致性,? 事物也是不生效的,最終也是一致的4、步驟6、7如果中間任何一個(gè)時(shí)刻斷電了,這時(shí)候情況就不一樣了,事物是生效的,因?yàn)閞edolog、binlog的數(shù)據(jù)都是完整的,服務(wù)器重啟后可以按照xid來去查看binlog、redolog中是否都存在,? 都存在該事物就是生效的。上面就是怎么保證事務(wù)一致性的根本原因
為什么要使用redolog?
回答這個(gè)問題之前,我們先看看redolog用圖形表示的
圖4是redolog的形象一點(diǎn)的表現(xiàn),并不是說redolog 長這個(gè)樣子,只是為了更形象;一般情況下redolog一組4個(gè)文件,每個(gè)文件1個(gè)G,其中write pos是指redolog當(dāng)前寫到什么位置了,check point是指上次刷臟結(jié)束的位置,當(dāng)write log和check point重合時(shí),所有的進(jìn)程停止,開始新一輪的刷臟操作。刷完后redolog清空開始下一輪的寫入,往返重復(fù)。
可能這樣表示有點(diǎn)抽象,讓我們看下圖5
從上圖中可以看的更形象一點(diǎn),在sql執(zhí)行的時(shí)候,會(huì)有磁盤IO將數(shù)據(jù)頁加載到內(nèi)存,然后在內(nèi)存中將數(shù)據(jù)修改,修改后的數(shù)據(jù)頁在內(nèi)存中叫做臟頁(叫臟頁因?yàn)楹痛疟P中的數(shù)據(jù)不一致啊),又因?yàn)樵趦?nèi)存中容易丟失,所以將數(shù)據(jù)頁的變更記錄如redolog中,隨著記錄插入、更新等操作的增多,redolog空間慢慢的滿了,這時(shí)候就開始刷臟操作了,page cleaner thread線程會(huì)將所有的臟頁數(shù)據(jù)刷新到磁盤,使得變更最終被持久化到磁盤。
講到這里一定還會(huì)有人不太理解,刷臟之前斷電了咋辦?
這就是redolog的另一個(gè)重要的作用,crash-safe能力,實(shí)現(xiàn)的邏輯是這樣的,斷電后內(nèi)存的數(shù)據(jù)都沒了,重啟后讀取redolog文件,因?yàn)閞edolog文件記錄的是在Innodb頁x的m處做了y的修改,所以根據(jù)redolog將涉及到的Innodb頁重新加載到內(nèi)存,根據(jù)redolog的記錄將內(nèi)存中的數(shù)據(jù)重新修改,這樣就能恢復(fù)斷電前的數(shù)據(jù)了。
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?完
下期預(yù)告:還是MySQL,敬請(qǐng)期待
本文首發(fā)自: 程序員阿牛
每日一問-常見MySQL面試問題3
什么是數(shù)據(jù)庫事務(wù),MySQL 為什么會(huì)使用 InnoDB 作為默認(rèn)選項(xiàng)?
1.原子性(一個(gè)原子事務(wù)中的所有操作要么全部成功,要么全部失?。?實(shí)現(xiàn)主要基于undo log(回滾日志)
2.一致性(數(shù)據(jù)庫總是從一個(gè)一致性的狀態(tài)轉(zhuǎn)換到另一個(gè)一致性的狀態(tài))
3. 隔離性(針對(duì)并發(fā)事務(wù)而言,事務(wù)必須在不干擾其他進(jìn)程或事務(wù)的前提下獨(dú)立執(zhí)行)
4.持久性(一旦事務(wù)提交成功,它對(duì)于數(shù)據(jù)的修改就會(huì)永久保存到數(shù)據(jù)庫中)
也就是我們常說的事務(wù)ACID,這樣才能保證事務(wù)中數(shù)據(jù)的正確性。
InnoDB支持事務(wù)安全,InnoDB支持表、行(默認(rèn))級(jí)鎖,而MyISAM支持表級(jí)鎖;
MySQL面試題(無答案版) 中高級(jí)必看
1、mysql記錄存儲(chǔ):mysql的數(shù)據(jù)是怎么組織的
2、頁內(nèi)記錄的維護(hù)(順序保證/插入策略/頁內(nèi)查詢)
3、MySQL內(nèi)存管理(頁面管理、頁面淘汰、LRU):全表掃描對(duì)內(nèi)存有什么影響? 如何避免熱數(shù)據(jù)被淘汰? 沒有空閑頁怎么辦?
4、InnoDB 加鎖的過程是如何實(shí)現(xiàn)的?常見鎖問題有那些?
5、MVCC是什么?如何實(shí)現(xiàn)多版本控制?如何解決寫沖突?
6、回滾日志Undo log如何實(shí)現(xiàn)多版本控制與保證事務(wù)的原子性?
7、undo log如何清理,為何InnoDB select count(*)? 這么慢?
8、重做日志Redo log如何實(shí)現(xiàn)事務(wù)持久性?
9、InnoDB行級(jí)鎖、間隙鎖、表級(jí)鎖如何實(shí)現(xiàn)的?
10、InnoDB加鎖過程如何實(shí)現(xiàn)的?
11、海量數(shù)據(jù)下 主鍵如何設(shè)計(jì)?
12、聚集索引、二級(jí)索引與聯(lián)合索引具備哪些特點(diǎn)?
13、在進(jìn)行索引優(yōu)化時(shí)應(yīng)該注意哪些問題/
14、MySQL如何進(jìn)行庫表的優(yōu)雅設(shè)計(jì)?
15、如何實(shí)現(xiàn)數(shù)據(jù)備份之延時(shí)庫部署
16、MySQL如何高效實(shí)現(xiàn)數(shù)據(jù)冗余部署
17、MySQL高可用方案有哪些
面試你應(yīng)該知道的 MySQL 的鎖
背景
數(shù)據(jù)庫的鎖是在多線程高并發(fā)的情況下用來保證數(shù)據(jù)穩(wěn)定性和一致性的一種機(jī)制。MySQL 根據(jù)底層存儲(chǔ)引擎的不同,鎖的支持粒度和實(shí)現(xiàn)機(jī)制也不同。MyISAM 只支持表鎖,InnoDB 支持行鎖和表鎖。目前 MySQL 默認(rèn)的存儲(chǔ)引擎是 InnoDB,這里主要介紹 InnoDB 的鎖。
使用 InnoDB 的兩大優(yōu)點(diǎn):一是支持事務(wù);二是支持行鎖。
在高并發(fā)的情況下事務(wù)的并發(fā)處理會(huì)帶來幾個(gè)問題
由于高并發(fā)事務(wù)帶來這幾個(gè)問題,所以就產(chǎn)生了事務(wù)的隔離級(jí)別
舉個(gè)例子
按照上面 1,2,3,4 的順序執(zhí)行會(huì)發(fā)現(xiàn)第 4 步被阻塞了,必須執(zhí)行完第 5 步后才能插入成功。這里我們會(huì)很奇怪明明鎖住的是uid=6 的這一行,為什么不能插入 5 呢?原因就是這里采用了 next-key 的算法,鎖住的是(3,10)整個(gè)區(qū)間。感興趣的可以試一下。
今天給大家分享了一下 MySQL 的 InnoDB 的事務(wù)以及鎖的一些知識(shí),通過自己的實(shí)際上手實(shí)踐對(duì)這塊更加熟悉了,希望大家在看的時(shí)候也可以動(dòng)手試試,這樣更能體會(huì),理解的更深刻。
當(dāng)前題目:面試mysql怎么樣,mysql基礎(chǔ)面試
本文鏈接:http://fisionsoft.com.cn/article/hdgges.html