16-MySQL 的運行機制是什麼?它有哪些引擎?

數據庫是 Java 程序員面試必問的知識點之一,它和 Java 的核心面試點共同組成了一個完整的技術面試。而數據庫一般泛指的就是 MySQL,因爲 MySQL 幾乎佔據了數據庫的半壁江山,即使有些公司沒有使用 MySQL 數據庫,如果你對 MySQL 足夠精通的話,也是會被他們錄取的。因爲數據庫的核心與原理基本是相通的,所以有了 MySQL 的基礎之後,再去熟悉其他數據庫也是非常快的,那麼接下來的幾個課時就讓我們好好的學習一下 MySQL。

我們本課時的面試題是,MySQL 是如何運行的?說一下它有哪些引擎?

典型回答

MySQL 的執行流程是這樣的,首先客戶端先要發送用戶信息去服務器端進行授權認證。如果使用的是命令行工具,通常需要輸入如下信息:

mysql -h 主機名(IP) -u 用戶名 -P 端口 -p

其中:

-h 表示要連接的數據庫服務器的主機名或者 IP 信息;
-u 表示數據庫的用戶名稱;
-P 表示數據庫服務器的端口號,
小寫的 -p 表示需要輸入數據庫的密碼。
具體使用示例,如下圖所示:
在這裏插入圖片描述
當輸入正確密碼之後可以連接到數據庫了,如果密碼輸入錯誤,則會提示“Access denied for user ‘xxx’@‘xxx’ (using password: YES)”密碼錯誤信息,如下圖所示:
在這裏插入圖片描述
當連接服務器端成功之後就可以正常的執行 SQL 命令了,MySQL 服務器拿到 SQL 命令之後,會使用 MySQL 的分析器解析 SQL 指令,同時會根據語法分析器驗證 SQL 指令,查詢 SQL 指令是否滿足 MySQL 的語法規則。如果不支持此語法,則會提示“SQL syntax”語法錯誤信息。

當分析器驗證並解析 SQL 命令之後,會進入優化器階段,執行生成計劃,並設置相應的索引;當上面的這些步驟都執行完之後,就進入了執行器階段,並開始正式執行 SQL 命令。同樣在執行命令之前,它會先對你的執行命令進行權限查詢,看看是否有操作某個表的權限,如果有相應的權限,執行器就去調用 MySQL 數據庫引擎提供的接口,執行相應的命令;如果是非查詢操作會記錄對應的操作日誌,再命令執行完成之後返回結果給客戶端,這就是整個 MySQL 操作的完整流程。

需要注意的是,如果執行的是 select 語句並且是 MySQL 8.0 之前的版本的話,則會去 MySQL 的查詢緩存中查看之前是否有執行過這條 SQL;如果緩存中可以查到,則會直接返回查詢結果,這樣查詢性能就會提升很高。

整個 SQL 的執行流程,如下圖所示:
在這裏插入圖片描述
我們可以使用 SHOW ENGINES 命令來查看 MySQL 數據庫使用的存儲引擎,如下圖所示:
在這裏插入圖片描述
常用的數據庫引擎有 InnoDB、MyISAM、MEMORY 等,其中 InnoDB 支持事務功能,而 MyISAM 不支持事務,但 MyISAM 擁有較高的插入和查詢的速度。而 MEMORY 是內存型的數據庫引擎,它會將表中的數據存儲到內存中,因爲它是內存級的數據引擎,因此具備最快速的查詢效率,但它的缺點是,重啓數據庫之後,所有數據都會丟失,因爲這些數據是存放在內存中的。

考點分析

此面試題考察的是面試者對 MySQL 基礎知識的掌握程度,以及對於 MySQL 引擎的瞭解程度,這些都是屬於 MySQL 最核心的原理之一,也是面試中常見的面試問題,它一般作爲數據庫面試題的開始題目,和此面試題相關的面試點還有以下幾個:

  • 查詢緩存在什麼問題?
  • 如何選擇數據庫的引擎?
  • InnoDB 自增索引的持久化問題。

知識擴展

1.查詢緩存的利弊

MySQL 8.0 之前可以正常的使用查詢緩存的功能,可通過“SHOW GLOBAL VARIABLES LIKE ‘query_cache_type’”命令查詢數據庫是否開啓了查詢緩存的功能,它的結果值有以下三項:

  • OFF,關閉了查詢緩存功能;
  • ON,開啓了查詢緩存功能;
  • DEMAND,在 sql 語句中指定 sql_cache 關鍵字纔會有查詢緩存,也就是說必須使用 sql_cache 纔可以把該 select 語句的查詢結果緩存起來,比如“select sql_cache name from token where tid=1010”語句。
    開啓和關閉查詢緩存可以通過修改 MySQL 的配置文件 my.cnf 進行修改,它的配置項如下:

query_cache_type = ON

注意:配置被更改之後需要重啓 MySQL 服務才能生效。

查詢緩存的功能要根據實際的情況進行使用,建議設置爲按需緩存(DEMAND)模式,因爲查詢緩存的功能並不是那麼好用。比如我們設置了 query_cache_type = ON,當我們好不容易緩存了很多查詢語句之後,任何一條對此表的更新操作都會把和這個表關聯的所有查詢緩存全部清空,那麼在更新頻率相對較高的業務中,查詢緩存功能完全是一個雞肋。因此,在 MySQL 8.0 的版本中已經完全移除了此功能,也就是說在 MySQL 8.0 之後就完全沒有查詢緩存這個概念和功能了。

2.如何選擇數據庫引擎

選擇數據庫引擎要從實際的業務情況入手,比如是否需要支持事務?是否需要支持外鍵?是否需要支持持久化?以及是否支持地理位置存儲以及索引等方面進行綜合考量。

我們最常用的數據庫引擎是 InnoDB,它是 MySQL 5.5.5 之後的默認引擎,其優點是支持事務,且支持 4 種隔離級別。

  • 讀未提交:也就是一個事務還沒有提交時,它做的變更就能被其他事務看到。
  • 讀已提交:指的是一個事務只有提交了之後,其他事務才能看得到它的變更。
  • 可重複讀:此方式爲默認的隔離級別,它是指一個事務在執行過程中(從開始到結束)看到的數據都是一致的,在這個過程中未提交的變更對其他事務也是不可見的。
  • 串行化:是指對同一行記錄的讀、寫都會添加讀鎖和寫鎖,後面訪問的事務必須等前一個事務執行完成之後才能繼續執行,所以這種事務的執行效率很低。
    InnoDB 還支持外鍵、崩潰後的快速恢復、支持全文檢索(需要 5.6.4+ 版本)、集羣索引,以及地理位置類型的存儲和索引等功能。

MyISAM 引擎是 MySQL 原生的引擎,但它並不支持事務功能,這也是後來被 InnoDB 替代爲默認引擎的主要原因。MyISAM 有獨立的索引文件,因此在讀取數據方面的性能很高,它也支持全文索引、地理位置存儲和索引等功能,但不支持外鍵。

InnoDB 和 MyISAM 都支持持久化,但 MEMORY 引擎是將數據直接存儲在內存中了,因此在重啓服務之後數據就會丟失,但它帶來的優點是執行速度很快,可以作爲臨時表來使用。

我們可以根據實際的情況設置相關的數據庫引擎,還可以針對不同的表設置不同的數據引擎,只需要在創建表的時候指定 engine=引擎名稱即可,SQL 代碼如下:

create table student(
   id int primary key auto_increment,
   uname varchar(60),
   age int
) engine=Memory;

3.InnoDB 自增主鍵

在面試的過程中我們經常看到這樣一道面試題:

在一個自增表裏面一共有 5 條數據,id 從 1 到 5,刪除了最後兩條數據,也就是 id 爲 4 和 5 的數據,之後重啓的 MySQL
服務器,又新增了一條數據,請問新增的數據 id 爲幾?

我們通常的答案是如果表爲 MyISAM 引擎,那麼 id 就是 6,如果是 InnoDB 那麼 id 就是 4。

但是這個情況在高版本的 InnoDB 中,也就是 MySQL 8.0 之後就不準確了,它的 id 就不是 4 了,而是 6 了。因爲在 MySQL 8.0 之後 InnoDB 會把索引持久化到日誌中,重啓服務之後自增索引是不會丟失的,因此答案是 6,這個需要面試者注意一下。

小結

本課時我們講了 MySQL 數據庫運行流程的幾個階段,先從連接器授權,再到分析器進行語法分析。如果是 MySQL 8.0 之前的 select 語句可能會先查詢緩存,如果有緩存則會直接返回結果給客戶端,否則會從分析器進入優化器生成 SQL 的執行計劃,然後交給執行器調用操作引擎執行相關的 SQL,再把結果返回給客戶端。我們還講了最常見的三種數據庫引擎 InnoDB、MyISAM、MEMORY,以及它們的利弊分析。最後講了 InnoDB 在高版本(8.0)之後可以持久化自增主鍵的小特性,希望可以幫助到你。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章