10道不得不會的MySQL基礎(chǔ)面試題
以下都是 MySQL常見面試題,相信大家都會有種及眼熟又陌生的感覺、看過可能在短暫的面試后又馬上忘記了。JavaPub在這里整理這些容易忘記的重點知識及解答,建議收藏,經(jīng)常溫習(xí)查閱。
評論區(qū)見
@
1. mysql有哪幾種log
2. MySQL的復(fù)制原理以及流程
3. 事物的4種隔離級別
4. 相關(guān)概念
5. MySQL數(shù)據(jù)庫幾個基本的索引類型
6. drop、delete與truncate的區(qū)
7. 數(shù)據(jù)庫的樂觀鎖和悲觀鎖是什么?
8. SQL優(yōu)化方式
9. 從鎖的類別上分MySQL都有哪些鎖呢?
推薦一篇非常不錯的文章,閱讀后更有利于了解MySQL【B樹和B+樹的區(qū)別】:https://mp.weixin.qq.com/s/RWkc2lNarKnn8Dc0HrP58g

1. mysql有哪幾種log
重做日志(redo log)、回滾日志(undo log)、二進(jìn)制日志(binlog)、錯誤日志(errorlog)、慢查詢?nèi)罩?slow query log)、一般查詢?nèi)罩?general log),中繼日志(relay log)
錯誤日志:記錄出錯信息,也記錄一些警告信息或者正確的信息。
查詢?nèi)罩荆河涗浰袑?shù)據(jù)庫請求的信息,不論這些請求是否得到了正確的執(zhí)行。
慢查詢?nèi)罩荆涸O(shè)置一個閾值,將運行時間超過該值的所有SQL語句都記錄到慢查詢的日志文件中。
二進(jìn)制日志:記錄對數(shù)據(jù)庫執(zhí)行更改的所有操作。
中繼日志:中繼日志也是二進(jìn)制日志,用來給slave 庫恢復(fù)
事務(wù)日志:重做日志redo和回滾日志undo
2. MySQL的復(fù)制原理以及流程
- 主:binlog線程——記錄下所有改變了數(shù)據(jù)庫數(shù)據(jù)的語句,放進(jìn)master上的binlog中。
- 從:io線程——在使用start slave 之后,負(fù)責(zé)從master上拉取 binlog 內(nèi)容,放進(jìn) 自己的relay log中。
- 從:sql執(zhí)行線程——執(zhí)行relay log中的語句。
3. 事物的4種隔離級別
隔離強(qiáng)度逐漸增強(qiáng),性能逐漸變差。
- 讀未提交(RU) READ UNCOMMITTED
- 讀已提交(RC) READ COMMITT
- 可重復(fù)讀(RR) REPEATABLE READ
- 串行化 SERIALIZABLE
事務(wù)具有原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)四個特性,簡稱 ACID,缺一不可。
4. 相關(guān)概念
臟讀
臟讀指的是讀到了其他事務(wù)未提交的數(shù)據(jù),未提交意味著這些數(shù)據(jù)可能會回滾,也就是可能最終不會存到數(shù)據(jù)庫中,也就是不存在的數(shù)據(jù)。讀到了并一定最終存在的數(shù)據(jù),這就是臟讀。
可重復(fù)讀
可重復(fù)讀指的是在一個事務(wù)內(nèi),最開始讀到的數(shù)據(jù)和事務(wù)結(jié)束前的任意時刻讀到的同一批數(shù)據(jù)都是一致的。通常針對數(shù)據(jù)更新(UPDATE)操作。
不可重復(fù)讀
對比可重復(fù)讀,不可重復(fù)讀指的是在同一事務(wù)內(nèi),不同的時刻讀到的同一批數(shù)據(jù)可能是不一樣的,可能會受到其他事務(wù)的影響,比如其他事務(wù)改了這批數(shù)據(jù)并提交了。通常針對數(shù)據(jù)更新(UPDATE)操作。
幻讀
幻讀是針對數(shù)據(jù)插入(INSERT)操作來說的。假設(shè)事務(wù) A 對某些行的內(nèi)容作了更改,但是還未提交,此時事務(wù) B 插入了與事務(wù) A 更改前的記錄相同的記錄行,并且在事務(wù) A 提交之前先提交了,而這時,在事務(wù) A 中查詢,會發(fā)現(xiàn)好像剛剛的更改對于某些數(shù)據(jù)未起作用,但其實是事務(wù) B 剛插入進(jìn)來的,讓用戶感覺很魔幻,感覺出現(xiàn)了幻覺,這就叫幻讀。
5. MySQL數(shù)據(jù)庫幾個基本的索引類型
普通索引、唯一索引、主鍵索引、全文索引
6. drop、delete與truncate的區(qū)
SQL中的drop、delete、truncate都表示刪除,但是三者有一些差別
1、delete和truncate只刪除表的數(shù)據(jù)不刪除表的結(jié)構(gòu) 2、速度,一般來說: drop> truncate >delete 3、delete語句是dml,這個操作會放到rollback segement中,事務(wù)提交之后才生效; 4、如果有相應(yīng)的trigger,執(zhí)行的時候?qū)⒈挥|發(fā). truncate,drop是ddl, 操作立即生效,原數(shù)據(jù)不放到rollback segment中,不能回滾. 操作不觸發(fā)trigger.
7. 數(shù)據(jù)庫的樂觀鎖和悲觀鎖是什么?
悲觀鎖的特點是先獲取鎖,再進(jìn)行業(yè)務(wù)操作,即 “悲觀” 的認(rèn)為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進(jìn)行業(yè)務(wù)操作。通常所說的 “一鎖二查三更新” 即指的是使用悲觀鎖。
通常來講在數(shù)據(jù)庫上的悲觀鎖需要數(shù)據(jù)庫本身提供支持,即通過常用的 select … for update 操作來實現(xiàn)悲觀鎖?!‘?dāng)數(shù)據(jù)庫執(zhí)行 select for update 時會獲取被 select 中的數(shù)據(jù)行的行鎖,因此其他并發(fā)執(zhí)行的 select for update 如果試圖選中同一行則會發(fā)生排斥(需要等待行鎖被釋放),因此達(dá)到鎖的效果。select for update 獲取的行鎖會在當(dāng)前事務(wù)結(jié)束時自動釋放,因此必須在事務(wù)中使用。
mysql 還有個問題是 select… for update 語句執(zhí)行中,如果數(shù)據(jù)表沒有添加索引或主鍵,所有掃描過的行都會被鎖上,這一點很容易造成問題。因此如果在 mysql 中用悲觀鎖務(wù)必要確定走了索引,而不是全表掃描。
樂觀鎖的特點先進(jìn)行業(yè)務(wù)操作,不到萬不得已不去拿鎖。即“樂觀”的認(rèn)為拿鎖多半是會成功的,因此在進(jìn)行完業(yè)務(wù)操作需要實際更新數(shù)據(jù)的最后一步再去拿一下鎖就好。
樂觀鎖在數(shù)據(jù)庫上的實現(xiàn)完全是邏輯的,不需要數(shù)據(jù)庫提供特殊的支持。一般的做法是在需要鎖的數(shù)據(jù)上增加一個版本號,或者時間戳。
樂觀鎖的兩種實現(xiàn)方式:
使用數(shù)據(jù)版本(Version)記錄機(jī)制實現(xiàn),這是樂觀鎖最常用的一種實現(xiàn)方式。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個版本標(biāo)識,一般是通過為數(shù)據(jù)庫表增加一個數(shù)字類型的 “version” 字段來實現(xiàn)。當(dāng)讀取數(shù)據(jù)時,將 version 字段的值一同讀出,數(shù)據(jù)每更新一次,對此 version 值加一。當(dāng)我們提交更新的時候,判斷數(shù)據(jù)庫表對應(yīng)記錄的當(dāng)前版本信息與第一次取出來的 version 值進(jìn)行比對,如果數(shù)據(jù)庫表當(dāng)前版本號與第一次取出來的 version 值相等,則予以更新,否則認(rèn)為是過期數(shù)據(jù)。
樂觀鎖定的第二種實現(xiàn)方式和第一種差不多,同樣是在需要樂觀鎖控制的table中增加一個字段,名稱無所謂,字段類型使用時間戳(timestamp),和上面的 version 類似,也是在更新提交的時候檢查當(dāng)前數(shù)據(jù)庫中數(shù)據(jù)的時間戳和自己更新前取到的時間戳進(jìn)行對比,如果一致則 OK,否則就是版本沖突。
8. SQL優(yōu)化方式
- 對查詢進(jìn)行優(yōu)化,應(yīng)盡量避免全表掃描,首先應(yīng)考慮在 where 及 order by 涉及的列上建立索引。
- 應(yīng)盡量避免在 where 子句中對字段進(jìn)行 null 值判斷,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描,如果索引是整形,那么可以在索引上設(shè)置默認(rèn)值 0,確保表中列沒有 null 值。
- 應(yīng)盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進(jìn)行全表掃描。
- 應(yīng)盡量避免在 where 子句中使用 or 來連接條件,否則將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。
- in 和 not in 也要慎用,否則會導(dǎo)致全表掃描。
- like ‘%abc%’ 也會導(dǎo)致全表掃描。
- 應(yīng)盡量避免在 where 子句中對字段進(jìn)行表達(dá)式操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。
- 應(yīng)盡量避免在 where 子句中對字段進(jìn)行函數(shù)操作,這將導(dǎo)致引擎放棄使用索引而進(jìn)行全表掃描。
- 在使用索引字段作為條件時,如果該索引是復(fù)合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統(tǒng)使用該索引,否則該索引將不會被使用,并且應(yīng)盡可能的讓字段順序與索引順序相一致。
- 很多時候用 exists 代替 in 是一個好的選擇。
9. 從鎖的類別上分MySQL都有哪些鎖呢?
從鎖的類別上來講,有共享鎖和排他鎖。
共享鎖: 又叫做讀鎖。當(dāng)用戶要進(jìn)行數(shù)據(jù)的讀取時,對數(shù)據(jù)加上共享鎖。共享鎖可以同時加上多個。
排他鎖: 又叫做寫鎖。當(dāng)用戶要進(jìn)行數(shù)據(jù)的寫入時,對數(shù)據(jù)加上排他鎖。排他鎖只可以加一個,他和其他的排他鎖,共享鎖都相斥。
參考:
1.?https://haicoder.net/note/mysql-interview/mysql-interview-optimistic-pessimism-lock.html
推薦閱讀:
