【MySQL面試】10道不得不會的MySQL基礎面試題


以下都是 MySQL常見面試題,相信大家都會有種及眼熟又陌生的感覺、看過可能在短暫的面試后又馬上忘記了。JavaPub在這里整理這些容易忘記的重點知識及解答建議收藏,經常溫習查閱

評論區見

@


推薦一篇非常不錯的文章,閱讀后更有利於了解MySQL【B樹和B+樹的區別】:https://mp.weixin.qq.com/s/RWkc2lNarKnn8Dc0HrP58g


1. mysql有哪幾種log

重做日志(redo log)、回滾日志(undo log)、二進制日志(binlog)、錯誤日志(errorlog)、慢查詢日志(slow query log)、一般查詢日志(general log),中繼日志(relay log)

錯誤日志:記錄出錯信息,也記錄一些警告信息或者正確的信息。

查詢日志:記錄所有對數據庫請求的信息,不論這些請求是否得到了正確的執行。

慢查詢日志:設置一個閾值,將運行時間超過該值的所有SQL語句都記錄到慢查詢的日志文件中。

二進制日志:記錄對數據庫執行更改的所有操作。

中繼日志:中繼日志也是二進制日志,用來給slave 庫恢復

事務日志:重做日志redo和回滾日志undo


2. MySQL的復制原理以及流程

  1. 主:binlog線程——記錄下所有改變了數據庫數據的語句,放進master上的binlog中。
  2. 從:io線程——在使用start slave 之后,負責從master上拉取 binlog 內容,放進 自己的relay log中。
  3. 從:sql執行線程——執行relay log中的語句。

3. 事物的4種隔離級別

隔離強度逐漸增強,性能逐漸變差。

  • 讀未提交(RU) READ UNCOMMITTED
  • 讀已提交(RC) READ COMMITT
  • 可重復讀(RR) REPEATABLE READ
  • 串行化 SERIALIZABLE

事務具有原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)四個特性,簡稱 ACID,缺一不可。


4. 相關概念

臟讀

臟讀指的是讀到了其他事務未提交的數據,未提交意味着這些數據可能會回滾,也就是可能最終不會存到數據庫中,也就是不存在的數據。讀到了並一定最終存在的數據,這就是臟讀。

可重復讀

可重復讀指的是在一個事務內,最開始讀到的數據和事務結束前的任意時刻讀到的同一批數據都是一致的。通常針對數據更新(UPDATE)操作。

不可重復讀

對比可重復讀,不可重復讀指的是在同一事務內,不同的時刻讀到的同一批數據可能是不一樣的,可能會受到其他事務的影響,比如其他事務改了這批數據並提交了。通常針對數據更新(UPDATE)操作。

幻讀

幻讀是針對數據插入(INSERT)操作來說的。假設事務 A 對某些行的內容作了更改,但是還未提交,此時事務 B 插入了與事務 A 更改前的記錄相同的記錄行,並且在事務 A 提交之前先提交了,而這時,在事務 A 中查詢,會發現好像剛剛的更改對於某些數據未起作用,但其實是事務 B 剛插入進來的,讓用戶感覺很魔幻,感覺出現了幻覺,這就叫幻讀。


5. MySQL數據庫幾個基本的索引類型

普通索引、唯一索引、主鍵索引、全文索引


6. drop、delete與truncate的區

SQL中的drop、delete、truncate都表示刪除,但是三者有一些差別

1、delete和truncate只刪除表的數據不刪除表的結構
2、速度,一般來說: drop> truncate >delete
3、delete語句是dml,這個操作會放到rollback segement中,事務提交之后才生效;
4、如果有相應的trigger,執行的時候將被觸發. truncate,drop是ddl, 操作立即生效,原數據不放到rollback segment中,不能回滾. 操作不觸發trigger.


7. 數據庫的樂觀鎖和悲觀鎖是什么?

悲觀鎖的特點是先獲取鎖,再進行業務操作,即 “悲觀” 的認為獲取鎖是非常有可能失敗的,因此要先確保獲取鎖成功再進行業務操作。通常所說的 “一鎖二查三更新” 即指的是使用悲觀鎖。

通常來講在數據庫上的悲觀鎖需要數據庫本身提供支持,即通過常用的 select … for update 操作來實現悲觀鎖。 當數據庫執行 select for update 時會獲取被 select 中的數據行的行鎖,因此其他並發執行的 select for update 如果試圖選中同一行則會發生排斥(需要等待行鎖被釋放),因此達到鎖的效果。select for update 獲取的行鎖會在當前事務結束時自動釋放,因此必須在事務中使用。

mysql 還有個問題是 select… for update 語句執行中,如果數據表沒有添加索引或主鍵,所有掃描過的行都會被鎖上,這一點很容易造成問題。因此如果在 mysql 中用悲觀鎖務必要確定走了索引,而不是全表掃描。

樂觀鎖的特點先進行業務操作,不到萬不得已不去拿鎖。即“樂觀”的認為拿鎖多半是會成功的,因此在進行完業務操作需要實際更新數據的最后一步再去拿一下鎖就好。

樂觀鎖在數據庫上的實現完全是邏輯的,不需要數據庫提供特殊的支持。一般的做法是在需要鎖的數據上增加一個版本號,或者時間戳。

樂觀鎖的兩種實現方式:

  1. 使用數據版本(Version)記錄機制實現,這是樂觀鎖最常用的一種實現方式。何謂數據版本?即為數據增加一個版本標識,一般是通過為數據庫表增加一個數字類型的 “version” 字段來實現。當讀取數據時,將 version 字段的值一同讀出,數據每更新一次,對此 version 值加一。當我們提交更新的時候,判斷數據庫表對應記錄的當前版本信息與第一次取出來的 version 值進行比對,如果數據庫表當前版本號與第一次取出來的 version 值相等,則予以更新,否則認為是過期數據。

  2. 樂觀鎖定的第二種實現方式和第一種差不多,同樣是在需要樂觀鎖控制的table中增加一個字段,名稱無所謂,字段類型使用時間戳(timestamp),和上面的 version 類似,也是在更新提交的時候檢查當前數據庫中數據的時間戳和自己更新前取到的時間戳進行對比,如果一致則 OK,否則就是版本沖突。


8. SQL優化方式

  1. 對查詢進行優化,應盡量避免全表掃描,首先應考慮在 where 及 order by 涉及的列上建立索引。
  2. 應盡量避免在 where 子句中對字段進行 null 值判斷,否則將導致引擎放棄使用索引而進行全表掃描,如果索引是整形,那么可以在索引上設置默認值 0,確保表中列沒有 null 值。
  3. 應盡量避免在 where 子句中使用 != 或 <> 操作符,否則將引擎放棄使用索引而進行全表掃描。
  4. 應盡量避免在 where 子句中使用 or 來連接條件,否則將導致引擎放棄使用索引而進行全表掃描。
  5. in 和 not in 也要慎用,否則會導致全表掃描。
  6. like ‘%abc%’ 也會導致全表掃描。
  7. 應盡量避免在 where 子句中對字段進行表達式操作,這將導致引擎放棄使用索引而進行全表掃描。
  8. 應盡量避免在 where 子句中對字段進行函數操作,這將導致引擎放棄使用索引而進行全表掃描。
  9. 在使用索引字段作為條件時,如果該索引是復合索引,那么必須使用到該索引中的第一個字段作為條件時才能保證系統使用該索引,否則該索引將不會被使用,並且應盡可能的讓字段順序與索引順序相一致。
  10. 很多時候用 exists 代替 in 是一個好的選擇。

9. 從鎖的類別上分MySQL都有哪些鎖呢?

從鎖的類別上來講,有共享鎖和排他鎖。

共享鎖: 又叫做讀鎖。 當用戶要進行數據的讀取時,對數據加上共享鎖。共享鎖可以同時加上多個。

排他鎖: 又叫做寫鎖。 當用戶要進行數據的寫入時,對數據加上排他鎖。排他鎖只可以加一個,他和其他的排他鎖,共享鎖都相斥。


參考:

1. https://haicoder.net/note/mysql-interview/mysql-interview-optimistic-pessimism-lock.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM