天天看點

MySQL執行流程?有哪些存儲引擎?

作者:Java大資料進階架構師

前言

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

MySQL 是如何運作的?說一下它有哪些引擎?

典型回答

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

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

其中:

  • -h 表示要連接配接的資料庫伺服器的主機名或者 IP 資訊;
  • -u 表示資料庫的使用者名稱;
  • -P 表示資料庫伺服器的端口号,
  • 小寫的 -p 表示需要輸入資料庫的密碼。

具體使用示例,如下圖所示:

MySQL執行流程?有哪些存儲引擎?

當輸入正确密碼之後可以連接配接到資料庫了,如果密碼輸入錯誤,則會提示“Access denied for user 'xxx'@'xxx' (using password: YES)”密碼錯誤資訊,如下圖所示:

MySQL執行流程?有哪些存儲引擎?

當連接配接伺服器端成功之後就可以正常的執行 SQL 指令了,MySQL 伺服器拿到 SQL 指令之後,會使用 MySQL 的分析器解析 SQL 指令,同時會根據文法分析器驗證 SQL 指令,查詢 SQL 指令是否滿足 MySQL 的文法規則。如果不支援此文法,則會提示“SQL syntax”文法錯誤資訊。

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

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

整個 SQL 的執行流程,如下圖所示:

MySQL執行流程?有哪些存儲引擎?

我們可以使用 SHOW ENGINES 指令來檢視 MySQL 資料庫使用的存儲引擎,如下圖所示:

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 種隔離級别。

  1. 讀未送出:也就是一個事務還沒有送出時,它做的變更就能被其他事務看到。
  2. 讀已送出:指的是一個事務隻有送出了之後,其他事務才能看得到它的變更。
  3. 可重複讀:此方式為預設的隔離級别,它是指一個事務在執行過程中(從開始到結束)看到的資料都是一緻的,在這個過程中未送出的變更對其他事務也是不可見的。
  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)之後可以持久化自增主鍵的小特性,希望可以幫助到你。

作者:Mr_Fire

連結:https://juejin.cn/post/7145794061872398372

繼續閱讀