數(shù)據(jù)庫八股文背誦版v0.2
大家好,我是小富~,我和BAT的小伙伴收集了市面上的大廠面試題,并配上了相關(guān)答案,放到了我的公眾號上。大家可以關(guān)注下方公眾號,回復(fù)關(guān)鍵詞:interviewtop 獲取題庫pdf版。
同時,我們根據(jù)題庫,也開發(fā)了互聯(lián)網(wǎng)題庫在線網(wǎng)站:也有不少熱心的網(wǎng)友貢獻(xiàn)了面試經(jīng)歷。題庫還處于更新中,歡迎大家訪問。http://interviewtop.top。同時,我的公眾號也會發(fā)一點(diǎn)廣告,負(fù)擔(dān)一下服務(wù)器成本,希望大家諒解。
目前題庫覆蓋公司有:各類銀行科技崗,百度,阿里,字節(jié),騰訊,美團(tuán),快手,網(wǎng)易,華為,shopee,京東。
題庫包括:計算網(wǎng)絡(luò),操作系統(tǒng),數(shù)據(jù)庫,Redis,Java基礎(chǔ),Java多線程,Java虛擬機(jī),設(shè)計模式,數(shù)據(jù)結(jié)構(gòu)與算法。
大家可以進(jìn)入網(wǎng)站搜索大廠對應(yīng)題庫的高頻面試題。
簡述數(shù)據(jù)庫三大范式
第一范式是最基本的范式。如果數(shù)據(jù)庫表中的所有字段值都是不可分解的原子值,就說明該數(shù)據(jù)庫表滿足了第一范式。
數(shù)據(jù)庫第二范式:關(guān)系模式必須滿足第一范式,并且所有非主屬性都完全依賴于主碼。注意,符合第二范式的關(guān)系模型可能還存在數(shù)據(jù)冗余、更新異常等問題。關(guān)系模型(學(xué)號,姓名,專業(yè)編號,專業(yè)名稱)中,學(xué)號->姓名,而專業(yè)編號->專業(yè)名稱,不滿足數(shù)據(jù)庫第二范式
數(shù)據(jù)庫第三范式:關(guān)系模型滿足第二范式,所有非主屬性對任何候選關(guān)鍵字都不存在傳遞依賴。即每個屬性都跟主鍵有直接關(guān)系而不是間接關(guān)系。接著以學(xué)生表舉例,對于關(guān)系模型(學(xué)號,姓名,年齡,性別,所在院校,院校地址,院校電話)院校地址,院校電話和學(xué)號不存在直接關(guān)系,因此不滿足第三范式。
簡述MySQL的架構(gòu)
MySQL可以分為應(yīng)用層,邏輯層,數(shù)據(jù)庫引擎層,物理層。
應(yīng)用層:負(fù)責(zé)和客戶端,響應(yīng)客戶端請求,建立連接,返回數(shù)據(jù)。
邏輯層:包括SQK接口,解析器,優(yōu)化器,Cache與buffer。
數(shù)據(jù)庫引擎層:有常見的MyISAM,InnoDB等等。
物理層:負(fù)責(zé)文件存儲,日志等等。
簡述執(zhí)行SQL語言的過程
客戶端首先通過連接器進(jìn)行身份認(rèn)證和權(quán)限相關(guān) 如果是執(zhí)行查詢語句的時候,會先查詢緩存,但MySQL 8.0 版本后該步驟移除。 沒有命中緩存的話,SQL 語句就會經(jīng)過解析器,分析語句,包括語法檢查等等。 通過優(yōu)化器,將用戶的SQL語句按照 MySQL 認(rèn)為最優(yōu)的方案去執(zhí)行。 執(zhí)行語句,并從存儲引擎返回數(shù)據(jù)。
簡述MySQL的共享鎖排它鎖
共享鎖也稱為讀鎖,相互不阻塞,多個客戶在同一時刻可以同時讀取同一個資源而不相互干擾。排他鎖也稱為寫鎖,會阻塞其他的寫鎖和讀鎖,確保在給定時間內(nèi)只有一個用戶能執(zhí)行寫入并防止其他用戶讀取正在寫入的同一資源。
簡述MySQL中的按粒度的鎖分類
表級鎖: 對當(dāng)前操作的整張表加鎖,實(shí)現(xiàn)簡單,加鎖快,但并發(fā)能力低。
行鎖: 鎖住某一行,如果表存在索引,那么記錄鎖是鎖在索引上的,如果表沒有索引,那么 InnoDB 會創(chuàng)建一個隱藏的聚簇索引加鎖。行級鎖能大大減少數(shù)據(jù)庫操作的沖突。其加鎖粒度最小,并發(fā)度高,但加鎖的開銷也最大,加鎖慢,會出現(xiàn)死鎖。
Gap 鎖:也稱為間隙鎖: 鎖定一個范圍但不包括記錄本身。其目的是為了防止同一事物的兩次當(dāng)前讀出現(xiàn)幻讀的情況。
Next-key Lock:行鎖+gap鎖。
如何解決數(shù)據(jù)庫死鎖
預(yù)先檢測到死鎖的循環(huán)依賴,并立即返回一個錯誤。 當(dāng)查詢的時間達(dá)到鎖等待超時的設(shè)定后放棄鎖請求。
簡述樂觀鎖和悲觀鎖
樂觀鎖:對于數(shù)據(jù)沖突保持一種樂觀態(tài)度,操作數(shù)據(jù)時不會對操作的數(shù)據(jù)進(jìn)行加鎖,只有到數(shù)據(jù)提交的時候才通過一種機(jī)制來驗(yàn)證數(shù)據(jù)是否存在沖突。
悲觀鎖:對于數(shù)據(jù)沖突保持一種悲觀態(tài)度,在修改數(shù)據(jù)之前把數(shù)據(jù)鎖住,然后再對數(shù)據(jù)進(jìn)行讀寫,在它釋放鎖之前任何人都不能對其數(shù)據(jù)進(jìn)行操作,直到前面一個人把鎖釋放后下一個人數(shù)據(jù)加鎖才可對數(shù)據(jù)進(jìn)行加鎖,然后才可以對數(shù)據(jù)進(jìn)行操作,一般數(shù)據(jù)庫本身鎖的機(jī)制都是基于悲觀鎖的機(jī)制實(shí)現(xiàn)的。
簡述InnoDB存儲引擎
InnoDB 是 MySQL 的默認(rèn)事務(wù)型引擎,支持事務(wù),表是基于聚簇索引建立的。支持表級鎖和行級鎖,支持外鍵,適合數(shù)據(jù)增刪改查都頻繁的情況。
InnoDB 采用 MVCC 來支持高并發(fā),并且實(shí)現(xiàn)了四個標(biāo)準(zhǔn)的隔離級別。其默認(rèn)級別是 REPEATABLE READ,并通過間隙鎖策略防止幻讀,間隙鎖使 InnoDB 不僅僅鎖定查詢涉及的行,還會對索引中的間隙進(jìn)行鎖定防止幻行的插入。
簡述MyISAM存儲引擎
MySQL5.1及之前,MyISAM 是默認(rèn)存儲引擎。MyISAM不支持事務(wù),Myisam支持表級鎖,不支持行級鎖,表不支持外鍵,該存儲引擎存有表的行數(shù),count運(yùn)算會更快。適合查詢頻繁,不適合對于增刪改要求高的情況
簡述Memory存儲引擎
Memory存儲引擎將所有數(shù)據(jù)都保存在內(nèi)存,不需要磁盤 IO。支持哈希索引,因此查找速度極快。Memory 表使用表級鎖,因此并發(fā)寫入的性能較低。
索引是什么?
索引是存儲引擎中用于快速找到記錄的一種數(shù)據(jù)結(jié)構(gòu)。在關(guān)系型數(shù)據(jù)庫中,索引具體是一種對數(shù)據(jù)庫中一列或多列的值進(jìn)行排序的存儲結(jié)構(gòu)。
為什么引入索引?
為了提高數(shù)據(jù)查詢的效率。索引對數(shù)據(jù)庫查詢良好的性能非常關(guān)鍵,當(dāng)表中數(shù)據(jù)量越來越大,索引對性能的影響越重要。
Mysql有哪些常見索引類型?
數(shù)據(jù)結(jié)構(gòu)角度
“
B-Tree索引 哈希索引 R-Tree索引 全文索引
”物理存儲角度
“
主鍵索引(聚簇索引):葉子節(jié)點(diǎn)存的是整行的數(shù)據(jù) 非主鍵索引(二級索引):葉子節(jié)點(diǎn)存的主鍵的值
”
簡述B-Tree與B+樹
B-Tree 是一種自平衡的多叉樹。每個節(jié)點(diǎn)都存儲關(guān)鍵字值。其左子節(jié)點(diǎn)的關(guān)鍵字值小于該節(jié)點(diǎn)關(guān)鍵字值,且右子節(jié)點(diǎn)的關(guān)鍵字值大于或等于該節(jié)點(diǎn)關(guān)鍵字值。
B+樹也是是一種自平衡的多叉樹。其基本定義與B樹相同,不同點(diǎn)在于數(shù)據(jù)只出現(xiàn)在葉子節(jié)點(diǎn),所有葉子節(jié)點(diǎn)增加了一個鏈指針,方便進(jìn)行范圍查詢。
B+樹中間節(jié)點(diǎn)不存放數(shù)據(jù),所以同樣大小的磁盤頁上可以容納更多節(jié)點(diǎn)元素,訪問葉子節(jié)點(diǎn)上關(guān)聯(lián)的數(shù)據(jù)也具有更好的緩存命中率。并且數(shù)據(jù)順序排列并且相連,所以便于區(qū)間查找和搜索。
B樹每一個節(jié)點(diǎn)都包含key和value,查詢效率比B+樹高。
簡述Hash索引
哈希索引對于每一行數(shù)據(jù)計算一個哈希碼,并將所有的哈希碼存儲在索引中,同時在哈希表中保存指向每個數(shù)據(jù)行的指針。只有 Memory 引擎顯式支持哈希索引。
Hash索引不支持范圍查詢,無法用于排序,也不支持部分索引列匹配查找。
簡述自適應(yīng)Hash索引
InnoDB對于頻繁使用的某些索引值,會在內(nèi)存中基于 B-Tree 索引之上再創(chuàng)鍵一個哈希索引,這也被稱為自適應(yīng)Hash索引。
簡述聚集索引和稀疏索引
聚集索引按每張表的主鍵構(gòu)建一棵B+樹,數(shù)據(jù)庫中的每個搜索鍵值都有一個索引記錄,每個數(shù)據(jù)頁通過雙向鏈表連接。表數(shù)據(jù)訪問更快,但表更新代價高。
稀疏索引不會為每個搜索關(guān)鍵字創(chuàng)建索引記錄。搜索過程需要,我們首先按索引記錄進(jìn)行操作,并按順序搜索,直到找到所需的數(shù)據(jù)為止。
簡述輔助索引與回表查詢
輔助索引是非聚集索引,葉子節(jié)點(diǎn)不包含記錄的全部數(shù)據(jù),包含了一個書簽用來告訴InnoDB哪里可以找到與索引相對應(yīng)的行數(shù)據(jù)。
通過輔助索引查詢,先通過書簽查到聚集索引,再根據(jù)聚集索引查對應(yīng)的值,需要兩次,也稱為回表查詢。
簡述聯(lián)合索引和最左匹配原則
聯(lián)合索引是指對表上的多個列的關(guān)鍵詞進(jìn)行索引。
對于聯(lián)合索引的查詢,如果精確匹配聯(lián)合索引的左邊連續(xù)一列或者多列,則mysql會一直向右匹配直到遇到范圍查詢(>,<,between,like)就停止匹配。Mysql會對第一個索引字段數(shù)據(jù)進(jìn)行排序,在第一個字段基礎(chǔ)上,再對第二個字段排序。
簡述覆蓋索引
覆蓋索引指一個索引包含或覆蓋了所有需要查詢的字段的值,不需要回表查詢,即索引本身存了對應(yīng)的值。
為什么數(shù)據(jù)庫不用紅黑樹用B+樹
紅黑樹的出度為 2,而 B Tree 的出度一般都非常大。紅黑樹的樹高 h 很明顯比 B Tree 大非常多,IO次數(shù)很多,導(dǎo)致會比較慢,因此檢索的次數(shù)也就更多。
B+Tree 相比于 B-Tree 更適合外存索引,擁有更大的出度,IO次數(shù)較少,檢索效率會更高。
基于主鍵索引的查詢和非主鍵索引的查詢有什么區(qū)別?
對于select * from 主鍵=XX,基于主鍵的普通查詢僅查找主鍵這棵樹,對于select * from 非主鍵=XX,基于非主鍵的查詢有可能存在回表過程(回到主鍵索引樹搜索的過程稱為回表),因?yàn)榉侵麈I索引葉子節(jié)點(diǎn)僅存主鍵值,無整行全部信息。
非主鍵索引的查詢一定會回表嗎?
不一定,當(dāng)查詢語句的要求字段全部命中索引,不用回表查詢。如select 主鍵 from 非主鍵=XX,此時非主鍵索引葉子節(jié)點(diǎn)即可拿到主鍵信息,不用回表。
簡述MySQL使用EXPLAIN 的關(guān)鍵字段
explain關(guān)鍵字用于分析sql語句的執(zhí)行情況,可以通過他進(jìn)行sql語句的性能分析。
type:表示連接類型,從好到差的類型排序?yàn)?/p>
system:系統(tǒng)表,數(shù)據(jù)已經(jīng)加載到內(nèi)存里。 const:常量連接,通過索引一次就找到。 eq_ref:唯一性索引掃描,返回所有匹配某個單獨(dú)值的行。 ref:非主鍵非唯一索引等值掃描,const或eq_ref改為普通非唯一索引。 range:范圍掃描,在索引上掃碼特定范圍內(nèi)的值。 index:索引樹掃描,掃描索引上的全部數(shù)據(jù)。 all:全表掃描。
key:顯示MySQL實(shí)際決定使用的鍵。
key_len:顯示MySQL決定使用的鍵長度,長度越短越好
Extra:額外信息
Using filesort:MySQL使用外部的索引排序,很慢需要優(yōu)化。 Using temporary:使用了臨時表保存中間結(jié)果,很慢需要優(yōu)化。 Using index:使用了覆蓋索引。 Using where:使用了where。
簡述MySQL優(yōu)化流程
通過慢日志定位執(zhí)行較慢的SQL語句 利用explain對這些關(guān)鍵字段進(jìn)行分析 根據(jù)分析結(jié)果進(jìn)行優(yōu)化
簡述MySQL中的日志log
redo log: 存儲引擎級別的log(InnoDB有,MyISAM沒有),該log關(guān)注于事務(wù)的恢復(fù).在重啟mysql服務(wù)的時候,根據(jù)redo log進(jìn)行重做,從而使事務(wù)有持久性。
undo log:是存儲引擎級別的log(InnoDB有,MyISAM沒有)保證數(shù)據(jù)的原子性,該log保存了事務(wù)發(fā)生之前的數(shù)據(jù)的一個版本,可以用于回滾,是MVCC的重要實(shí)現(xiàn)方法之一。
bin log:數(shù)據(jù)庫級別的log,關(guān)注恢復(fù)數(shù)據(jù)庫的數(shù)據(jù)。
簡述事務(wù)
事務(wù)內(nèi)的語句要么全部執(zhí)行成功,要么全部執(zhí)行失敗。
事務(wù)滿足如下幾個特性:
原子性(Atomicity): “
一個事務(wù)中的所有操作要么全部完成,要么全部不完成。
”一致性(Consistency): “
事務(wù)執(zhí)行前后數(shù)據(jù)庫的狀態(tài)保存一致。
”隔離性(Isolation) “
多個并發(fā)事務(wù)對數(shù)據(jù)庫進(jìn)行操作,事務(wù)間互不干擾。
”持久性(Durability) “
事務(wù)執(zhí)行完畢,對數(shù)據(jù)的修改是永久的,即使系統(tǒng)故障也不會丟失
”
數(shù)據(jù)庫中多個事務(wù)同時進(jìn)行可能會出現(xiàn)什么問題?
丟失修改 臟讀:當(dāng)前事務(wù)可以查看到別的事務(wù)未提交的數(shù)據(jù)。 不可重讀:在同一事務(wù)中,使用相同的查詢語句,同一數(shù)據(jù)資源莫名改變了。 幻讀:在同一事務(wù)中,使用相同的查詢語句,莫名多出了一些之前不存在的數(shù)據(jù),或莫名少了一些原先存在的數(shù)據(jù)。
SQL的事務(wù)隔離級別有哪些?
讀未提交: “
一個事務(wù)還沒提交,它做的變更就能被別的事務(wù)看到。
”讀提交: “
一個事務(wù)提交后,它做的變更才能被別的事務(wù)看到。
”可重復(fù)讀: “
一個事務(wù)執(zhí)行過程中看到的數(shù)據(jù)總是和事務(wù)啟動時看到的數(shù)據(jù)是一致的。在這個級別下事務(wù)未提交,做出的變更其它事務(wù)也看不到。
”串行化: “
對于同一行記錄進(jìn)行讀寫會分別加讀寫鎖,當(dāng)發(fā)生讀寫鎖沖突,后面執(zhí)行的事務(wù)需等前面執(zhí)行的事務(wù)完成才能繼續(xù)執(zhí)行。
”
什么是MVCC?
MVCC為多版本并發(fā)控制,即同一條記錄在系統(tǒng)中存在多個版本。其存在目的是在保證數(shù)據(jù)一致性的前提下提供一種高并發(fā)的訪問性能。對數(shù)據(jù)讀寫在不加讀寫鎖的情況下實(shí)現(xiàn)互不干擾,從而實(shí)現(xiàn)數(shù)據(jù)庫的隔離性,在事務(wù)隔離級別為讀提交和可重復(fù)讀中使用到。
在InnoDB中,事務(wù)在開始前會向事務(wù)系統(tǒng)申請一個事務(wù)ID,該ID是按申請順序嚴(yán)格遞增的。每行數(shù)據(jù)具有多個版本,每次事務(wù)更新數(shù)據(jù)都會生成新的數(shù)據(jù)版本,而不會直接覆蓋舊的數(shù)據(jù)版本。數(shù)據(jù)的行結(jié)構(gòu)中包含多個信息字段。其中實(shí)現(xiàn)MVCC的主要涉及最近更改該行數(shù)據(jù)的事務(wù)ID(DB_TRX_ID)和可以找到歷史數(shù)據(jù)版本的指針(DB_ROLL_PTR)。InnoDB在每個事務(wù)開啟瞬間會為其構(gòu)造一個記錄當(dāng)前已經(jīng)開啟但未提交的事務(wù)ID的視圖數(shù)組。通過比較鏈表中的事務(wù)ID與該行數(shù)據(jù)的值與對應(yīng)的DB_TRX_ID,并通過DB_ROLL_PTR找到歷史數(shù)據(jù)的值以及對應(yīng)的DB_TRX_ID來決定當(dāng)前版本的數(shù)據(jù)是否應(yīng)該被當(dāng)前事務(wù)所見。最終實(shí)現(xiàn)在不加鎖的情況下保證數(shù)據(jù)的一致性。
讀提交和可重復(fù)讀都基于MVCC實(shí)現(xiàn),有什么區(qū)別?
在可重復(fù)讀級別下,只會在事務(wù)開始前創(chuàng)建視圖,事務(wù)中后續(xù)的查詢共用一個視圖。而讀提交級別下每個語句執(zhí)行前都會創(chuàng)建新的視圖。因此對于可重復(fù)讀,查詢只能看到事務(wù)創(chuàng)建前就已經(jīng)提交的數(shù)據(jù)。而對于讀提交,查詢能看到每個語句啟動前已經(jīng)提交的數(shù)據(jù)。
InnoDB如何保證事務(wù)的原子性、持久性和一致性?
利用undo log保障原子性。該log保存了事務(wù)發(fā)生之前的數(shù)據(jù)的一個版本,可以用于回滾,從而保證事務(wù)原子性。
利用redo log保證事務(wù)的持久性,該log關(guān)注于事務(wù)的恢復(fù).在重啟mysql服務(wù)的時候,根據(jù)redo log進(jìn)行重做,從而使事務(wù)有持久性。
利用undo log+redo log保障一致性。事務(wù)中的執(zhí)行需要redo log,如果執(zhí)行失敗,需要undo log 回滾。
MySQL是如何保證主備一致的?
MySQL通過binlog(二進(jìn)制日志)實(shí)現(xiàn)主備一致。binlog記錄了所有修改了數(shù)據(jù)庫或可能修改數(shù)據(jù)庫的語句,而不會記錄select、show這種不會修改數(shù)據(jù)庫的語句。在備份的過程中,主庫A會有一個專門的線程將主庫A的binlog發(fā)送給 備庫B進(jìn)行備份。其中binlog有三種記錄格式:
statement:記錄對數(shù)據(jù)庫進(jìn)行修改的語句本身,有可能會記錄一些額外的相關(guān)信息。優(yōu)點(diǎn)是binlog日志量少,IO壓力小,性能較高。缺點(diǎn)是由于記錄的信息相對較少,在不同庫執(zhí)行時由于上下文的環(huán)境不同可能導(dǎo)致主備不一致。 row:記錄對數(shù)據(jù)庫做出修改的語句所影響到的數(shù)據(jù)行以及對這些行的修改。比如當(dāng)修改涉及多行數(shù)據(jù),會把涉及的每行數(shù)據(jù)都記錄到binlog。優(yōu)點(diǎn)是能夠完全的還原或者復(fù)制日志被記錄時的操作。缺點(diǎn)是日志量占用空間較大,IO壓力大,性能消耗較大。 mixed:混合使用上述兩種模式,一般的語句使用statment方式進(jìn)行保存,如果遇到一些特殊的函數(shù),則使用row模式進(jìn)行記錄。MySQL自己會判斷這條SQL語句是否可能引起主備不一致,如果有可能,就用row格式, 否則就用statement格式。但是在生產(chǎn)環(huán)境中,一般會使用row模式。
redo log與binlog的區(qū)別?
redo log是InnoDB引擎特有的,只記錄該引擎中表的修改記錄。binlog是MySQL的Server層實(shí)現(xiàn)的,會記錄所有引擎對數(shù)據(jù)庫的修改。 redo log是物理日志,記錄的是在具體某個數(shù)據(jù)頁上做了什么修改;binlog是邏輯日志,記錄的是這個語句的原始邏輯。 redo log是循環(huán)寫的,空間固定會用完;binlog是可以追加寫入的,binlog文件寫到一定大小后會切換到下一個,并不會覆蓋以前的日志。
crash-safe能力是什么?
InnoDB通過redo log保證即使數(shù)據(jù)庫發(fā)生異常重啟,之前提交的記錄都不會丟失,這個能力稱為crash-safe。
WAL技術(shù)是什么?
WAL的全稱是Write-Ahead Logging,它的關(guān)鍵點(diǎn)就是先寫日志,再寫磁盤。事務(wù)在提交寫入磁盤前,會先寫到redo log里面去。如果直接寫入磁盤涉及磁盤的隨機(jī)I/O訪問,涉及磁盤隨機(jī)I/O訪問是非常消耗時間的一個過程,相比之下先寫入redo log,后面再找合適的時機(jī)批量刷盤能提升性能。
兩階段提交是什么?
為了保證binlog和redo log兩份日志的邏輯一致,最終保證恢復(fù)到主備數(shù)據(jù)庫的數(shù)據(jù)是一致的,采用兩階段提交的機(jī)制。
執(zhí)行器調(diào)用存儲引擎接口,存儲引擎將修改更新到內(nèi)存中后,將修改操作記錄redo log中,此時redo log處于prepare狀態(tài)。 存儲引擎告知執(zhí)行器執(zhí)行完畢,執(zhí)行器生成這個操作對應(yīng)的binlog,并把binlog寫入磁盤。 執(zhí)行器調(diào)用引擎的提交事務(wù)接口,引擎把剛剛寫入的redo log改成提交commit狀態(tài),更新完成。
只靠binlog可以支持?jǐn)?shù)據(jù)庫崩潰恢復(fù)嗎?
不可以。歷史原因:
InnoDB在作為MySQL的插件加入MySQL引擎家族之前,就已經(jīng)是一個提供了崩潰恢復(fù)和事務(wù)支持的引擎了。InnoDB接入了MySQL后,發(fā)現(xiàn)既然binlog沒有崩潰恢復(fù)的能力,那引入InnoDB原有的redo log來保證崩潰恢復(fù)能力。實(shí)現(xiàn)原因: binlog沒有記錄數(shù)據(jù)頁修改的詳細(xì)信息,不具備恢復(fù)數(shù)據(jù)頁的能力。binlog記錄著數(shù)據(jù)行的增刪改,但是不記錄事務(wù)對數(shù)據(jù)頁的改動,這樣細(xì)致的改動只記錄在redo log中。當(dāng)一個事務(wù)做增刪改時,其實(shí)涉及到的數(shù)據(jù)頁改動非常細(xì)致和復(fù)雜,包括行的字段改動以及行頭部以及數(shù)據(jù)頁頭部的改動,甚至b+tree會因?yàn)椴迦胍恍卸l(fā)生若干次頁面分裂,那么事務(wù)也會把所有這些改動記錄下來到redo log中。因?yàn)閿?shù)據(jù)庫系統(tǒng)進(jìn)程crash時刻,磁盤上面頁面鏡像可以非?;靵y,其中有些頁面含有一些正在運(yùn)行著的事務(wù)的改動,而一些已提交的事務(wù)的改動并沒有刷上磁盤。事務(wù)恢復(fù)過程可以理解為是要把沒有提交的事務(wù)的頁面改動都去掉,并把已經(jīng)提交的事務(wù)的頁面改動都加上去這樣一個過程。這些信息,都是binlog中沒有記錄的,只記錄在了存儲引擎的redo log中。 操作寫入binlog可細(xì)分為write和fsync兩個過程,write指的就是指把日志寫入到文件系統(tǒng)的page cache,并沒有把數(shù)據(jù)持久化到磁盤,fsync才是將數(shù)據(jù)持久化到磁盤的操作。通過參數(shù)設(shè)置sync_binlog為0的時候,表示每次提交事務(wù)都只write,不fsync。此時數(shù)據(jù)庫崩潰可能導(dǎo)致部分提交的事務(wù)以及binlog日志由于沒有持久化而丟失。
簡述MySQL主從復(fù)制
MySQL提供主從復(fù)制功能,可以方便的實(shí)現(xiàn)數(shù)據(jù)的多處自動備份,不僅能增加數(shù)據(jù)庫的安全性,還能進(jìn)行讀寫分離,提升數(shù)據(jù)庫負(fù)載性能。
主從復(fù)制流程:
在事務(wù)完成之前,主庫在binlog上記錄這些改變,完成binlog寫入過程后,主庫通知存儲引擎提交事物 從庫將主庫的binlog復(fù)制到對應(yīng)的中繼日志,即開辟一個I/O工作線程,I/O線程在主庫上打開一個普通的連接,然后開始binlog dump process,將這些事件寫入中繼日志。從主庫的binlog中讀取事件,如果已經(jīng)讀到最新了,線程進(jìn)入睡眠并等待ma主庫產(chǎn)生新的事件。
讀寫分離:即只在MySQL主庫上寫,只在MySQL從庫上讀,以減少數(shù)據(jù)庫壓力,提高性能。
MySQL數(shù)據(jù)存儲過程
一般來說,普通的SQL語句需要先編譯然后執(zhí)行,而存儲過程可以理解為為了完成特定功能的已經(jīng)編譯后的SQL語句集。用戶可通過存儲過程的名字并給定參數(shù)來調(diào)用。
MySQL數(shù)據(jù)庫觸發(fā)器
觸發(fā)器簡單來說就是監(jiān)視某種情況,并觸發(fā)某種操作。當(dāng)觸發(fā)器所在表上出現(xiàn)指定事件(insert/update/delete)時,可指定時間(after/before)執(zhí)行特定事件(insert/update/delete)。
SQL優(yōu)化方法
核心就是避免全表掃描,多走索引。列舉常用的一些優(yōu)化方法:
盡量對利用字段較多的建立索引,即在 where 及 order by 涉及的列上建立索引。 盡量避免在 where 子句中使用 or ,null值判斷,in 和對字段進(jìn)行表達(dá)式操作 建立索引時需要多考慮最左匹配原則
mysql的操作 增刪改查
增:INSERT INTO 表名(字段名1,字段名2,…)VALUES(值1,值2,…)
刪:DELETE FROM 表名 [WHERE 條件表達(dá)式] TRUNCTE [TABLE ] 表名(刪除整張表數(shù)據(jù))
改:UPDATE 表名 SET 字段名1=值1,[ ,字段名2=值2,…] [ WHERE 條件表達(dá)式 ]
查:SELECT 字段名1,字段名2,… FROM 表名 [ WHERE 條件表達(dá)式 ]
mysql的查詢語法順序
where、group by、having、order by、limit
delete和truncate區(qū)別
delete是數(shù)據(jù)操縱語言(DML),其按行刪除,支持where語句,執(zhí)行操作采用行鎖,執(zhí)行操作時會將該操作記錄在redo和undo中,因此支持回滾。
truncate是數(shù)據(jù)定義語言(DDL),其操作隱式提交,不支持回滾,不支持where,刪除時采用表級鎖進(jìn)行刪除。
什么情況下分表合適
針對存儲了百萬級乃至千萬級條記錄的大表。數(shù)據(jù)庫在查詢和插入的時候耗時太長,可通過分表,將大表拆分成小表,提升數(shù)據(jù)庫性能。
關(guān)系型數(shù)據(jù)庫與非關(guān)系型數(shù)據(jù)庫區(qū)別
關(guān)系型數(shù)據(jù)庫采用了關(guān)系模型(可以簡單理解為二維表格類型)組織數(shù)據(jù),一般可以遵守事務(wù)的ACID特性 不是由關(guān)系模型進(jìn)行存儲的均可視作非關(guān)系型數(shù)據(jù)庫,比如以鍵值對的redis,圖數(shù)據(jù)庫等。
樂觀鎖如何保證一致性
樂觀鎖保持一致性主要通過兩個方法。
通過數(shù)據(jù)屬性中,增加版本號屬性,進(jìn)行比較,比較目前操作數(shù)據(jù)是否是最新版本。 CAS(compare and swap)即在對數(shù)據(jù)修改過程中,采用CAS算法,保證在并發(fā)下的一致性。
mysql為什么要用自增id作為主鍵
直接原因是其存儲機(jī)制。MySQL采用數(shù)據(jù)頁進(jìn)行數(shù)據(jù)存儲。如果采用自增主鍵,在原先數(shù)據(jù)頁寫滿的情況下,MySQL對于新數(shù)據(jù),直接開辟新頁進(jìn)行寫操作。如果不采用自增主鍵,為保障索引有序,新數(shù)據(jù)需插入到合適位置上,由此針對頁數(shù)據(jù)滿的情況下,MySQL需要申請新頁,并將一部分之前的頁數(shù)據(jù)挪到新頁上,保證按索引有序存儲,相對自增主鍵IO開銷更大。
大數(shù)據(jù)量的分頁查詢怎么優(yōu)化
定位對應(yīng)索引id所處的偏移位置,之后進(jìn)行查詢。
select * from table where num = 8 limit 100000,1;
變?yōu)?/p>
select * from table where num = 8 and id >= (
select id from table where num = 8 limit 100000,1
) limit 100;
由于id走了索引,因此速度會有一定提升。
分庫分表怎么做
對于分庫,即將一個數(shù)據(jù)庫拆分為多個庫??梢酝ㄟ^水平拆分,或者垂直拆分的方式,將表進(jìn)行拆分。一般可以采用中間件Sharding-JDBC進(jìn)行分庫分表。
char和varchar區(qū)別
CHAR的長度是不可變的,而VARCHAR的長度是可變的。因此CHAR效率高,VARCHAR效率偏低。
臟讀是什么,如何解決
一個事務(wù)讀取了另一個事務(wù)修改但未提交的數(shù)據(jù)
將事務(wù)隔離級別設(shè)置為:讀已提交,串行化,可重復(fù)讀進(jìn)行解決。
不可重復(fù)讀是什么,如何解決
一個事務(wù)連續(xù)讀兩次數(shù)據(jù),但結(jié)果不一樣。(兩次讀之間,數(shù)據(jù)被其他事務(wù)修改)。
將事務(wù)隔離級別設(shè)置為:串行化,可重復(fù)讀進(jìn)行解決。
幻讀是什么,如何解決
一個事務(wù)連續(xù)讀兩次數(shù)據(jù),讀取數(shù)據(jù)量不一樣。(兩次讀之前,數(shù)據(jù)被其他事務(wù)刪除或新增)。
將事務(wù)隔離級別設(shè)置為:串行化,或在innodb引擎中有g(shù)ap鎖的情況下設(shè)置可重復(fù)讀進(jìn)行解決。
丟失修改是什么
數(shù)據(jù)被兩個事務(wù)連續(xù)修改,導(dǎo)致第一個事務(wù)的修改被第二個事務(wù)覆蓋丟失。
簡述主鍵索引和唯一索引
主鍵是能夠唯一標(biāo)識表中某一行的屬性或?qū)傩越M。對于表創(chuàng)建時未指定唯一索引的情況下,數(shù)據(jù)庫會自動生成某一隱藏字段,作為唯一索引。
唯一索引是在表上一個或者多個字段組合建立的索引。
什么時候需要創(chuàng)建索引
需要頻繁被作為查詢條件的字段 查詢過程中排序的字段創(chuàng)建索引 查詢過程中統(tǒng)計或者分組的字段
何時索引會失效
復(fù)合索引不滿足最左匹配原則 查詢條件有or where 查詢語句對索引列有數(shù)學(xué)運(yùn)算或函數(shù)
Mysql varchar字段怎么存儲
varchar字段開頭包含一個變長字段的實(shí)際長度,后面存儲的是真實(shí)字符。

