MySQL 的運行機制是什么?它有哪些引擎?
MySQL 是如何運行的
MySQL 的執(zhí)行流程是這樣的:
1、首先客戶端先要發(fā)送用戶信息去服務(wù)器端進行授權(quán)認(rèn)證。
如果使用的是命令行工具,通常需要輸入如下信息:
mysql -h 主機名(IP) -u 用戶名 -P 端口 -p其中:
-h 表示要連接的數(shù)據(jù)庫服務(wù)器的主機名或者 IP 信息;
-u 表示數(shù)據(jù)庫的用戶名稱;
-P 表示數(shù)據(jù)庫服務(wù)器的端口號,
小寫的 -p 表示需要輸入數(shù)據(jù)庫的密碼。具體使用示例,如下圖所示:

2、當(dāng)輸入正確密碼之后可以連接到數(shù)據(jù)庫了,如果密碼輸入錯誤,則會提示“Access denied for user 'xxx'@'xxx' (using password: YES)”密碼錯誤信息,如下圖所示:

3、當(dāng)連接服務(wù)器端成功之后就可以正常的執(zhí)行 SQL 命令了,MySQL 服務(wù)器拿到 SQL 命令之后,會使用 MySQL 的分析器解析 SQL 指令,同時會根據(jù)語法分析器驗證 SQL 指令,查詢 SQL 指令是否滿足 MySQL 的語法規(guī)則。如果不支持此語法,則會提示“SQL syntax”語法錯誤信息。
4、當(dāng)分析器驗證并解析 SQL 命令之后,會進入優(yōu)化器階段,執(zhí)行生成計劃,并設(shè)置相應(yīng)的索引;當(dāng)上面的這些步驟都執(zhí)行完之后,就進入了執(zhí)行器階段,并開始正式執(zhí)行 SQL 命令。同樣在執(zhí)行命令之前,它會先對你的執(zhí)行命令進行權(quán)限查詢,看看是否有操作某個表的權(quán)限,如果有相應(yīng)的權(quán)限,執(zhí)行器就去調(diào)用 MySQL 數(shù)據(jù)庫引擎提供的接口,執(zhí)行相應(yīng)的命令;如果是非查詢操作會記錄對應(yīng)的操作日志,
注意 :如果執(zhí)行的是 select 語句并且是 MySQL 8.0 之前的版本的話,則會去 MySQL 的查詢緩存中查看之前是否有執(zhí)行過這條 SQL;如果緩存中可以查到,則會直接返回查詢結(jié)果,這樣查詢性能就會提升很高。
流程圖如下:

說一下它有哪些引擎
我們可以使用 SHOW ENGINES 命令來查看 MySQL 數(shù)據(jù)庫使用的存儲引擎,如下圖所示:

常用的數(shù)據(jù)庫引擎有 InnoDB、MyISAM、MEMORY 等,其中 InnoDB 支持事務(wù)功能,而 MyISAM 不支持事務(wù),但 MyISAM 擁有較高的插入和查詢的速度。而 MEMORY 是內(nèi)存型的數(shù)據(jù)庫引擎,它會將表中的數(shù)據(jù)存儲到內(nèi)存中,因為它是內(nèi)存級的數(shù)據(jù)引擎,因此具備最快速的查詢效率,但它的缺點是,重啟數(shù)據(jù)庫之后,所有數(shù)據(jù)都會丟失,因為這些數(shù)據(jù)是存放在內(nèi)存中的。
查詢緩存的利弊
MySQL 8.0 之前可以正常的使用查詢緩存的功能,可通過“SHOW GLOBAL VARIABLES LIKE 'query_cache_type'”命令查詢數(shù)據(jù)庫是否開啟了查詢緩存的功能,它的結(jié)果值有以下三項:
1、OFF,關(guān)閉了查詢緩存功能
2、ON,開啟了查詢緩存功能;
3、DEMAND,在 sql 語句中指定 sql_cache 關(guān)鍵字才會有查詢緩存,也就是說必須使用 sql_cache 才可以把該 select 語句的查詢結(jié)果緩存起來,比如“select sql_cache name from token where tid=1010”語句。
開啟和關(guān)閉查詢緩存可以通過修改 MySQL 的配置文件 my.cnf 進行修改,它的配置項如下:
query_cache_type = ON查詢緩存的功能要根據(jù)實際的情況進行使用,建議設(shè)置為按需緩存(DEMAND)模式,因為查詢緩存的功能并不是那么好用。比如我們設(shè)置了 query_cache_type = ON,當(dāng)我們好不容易緩存了很多查詢語句之后,任何一條對此表的更新操作都會把和這個表關(guān)聯(lián)的所有查詢緩存全部清空,那么在更新頻率相對較高的業(yè)務(wù)中,查詢緩存功能完全是一個雞肋。因此,在 MySQL 8.0 的版本中已經(jīng)完全移除了此功能,也就是說在 MySQL 8.0 之后就完全沒有查詢緩存這個概念和功能了。
如何選擇數(shù)據(jù)庫引擎
選擇數(shù)據(jù)庫引擎要從實際的業(yè)務(wù)情況入手,比如是否需要支持事務(wù)?是否需要支持外鍵?是否需要支持持久化?以及是否支持地理位置存儲以及索引等方面進行綜合考量。
我們最常用的數(shù)據(jù)庫引擎是 InnoDB,它是 MySQL 5.5.5 之后的默認(rèn)引擎,其優(yōu)點是支持事務(wù),且支持 4 種隔離級別。
1、讀未提交:也就是一個事務(wù)還沒有提交時,它做的變更就能被其他事務(wù)看到。
2、
3、可重復(fù)讀:此方式為默認(rèn)的隔離級別,它是指一個事務(wù)在執(zhí)行過程中(從開始到結(jié)束)看到的數(shù)據(jù)都是一致的,在這個過程中未提交的變更對其他事務(wù)也是不可見的。
4、串行化:是指對同一行記錄的讀、寫都會添加讀鎖和寫鎖,后面訪問的事務(wù)必須等前一個事務(wù)執(zhí)行完成之后才能繼續(xù)執(zhí)行,所以這種事務(wù)的執(zhí)行效率很低。
InnoDB 還支持外鍵、崩潰后的快速恢復(fù)、支持全文檢索(需要 5.6.4+ 版本)、集群索引,以及地理位置類型的存儲和索引等功能。
MyISAM 引擎是 MySQL 原生的引擎,但它并不支持事務(wù)功能,這也是后來被 InnoDB 替代為默認(rèn)引擎的主要原因。MyISAM 有獨立的索引文件,因此在讀取數(shù)據(jù)方面的性能很高,它也支持全文索引、地理位置存儲和索引等功能,但不支持外鍵。
InnoDB 和 MyISAM 都支持持久化,但 MEMORY 引擎是將數(shù)據(jù)直接存儲在內(nèi)存中了,因此在重啟服務(wù)之后數(shù)據(jù)就會丟失,但它帶來的優(yōu)點是執(zhí)行速度很快,可以作為臨時表來使用。
我們可以根據(jù)實際的情況設(shè)置相關(guān)的數(shù)據(jù)庫引擎,還可以針對不同的表設(shè)置不同的數(shù)據(jù)引擎,只需要在創(chuàng)建表的時候指定 engine=引擎名稱即可,SQL 代碼如下:
create table student(id int primary key auto_increment,uname varchar(60),age int) engine=Memory;
InnoDB 自增主鍵
在面試的過程中我們經(jīng)常看到這樣一道面試題:
在一個自增表里面一共有 5 條數(shù)據(jù),id 從 1 到 5,刪除了最后兩條數(shù)據(jù),也就是 id 為 4 和 5 的數(shù)據(jù),之后重啟的 MySQL 服務(wù)器,又新增了一條數(shù)據(jù),請問新增的數(shù)據(jù) id 為幾?我們通常的答案是如果表為 MyISAM 引擎,那么 id 就是 6,如果是 InnoDB 那么 id 就是 4。
但是這個情況在高版本的 InnoDB 中,也就是 MySQL 8.0 之后就不準(zhǔn)確了,它的 id 就不是 4 了,而是 6 了。因為在 MySQL 8.0 之后 InnoDB 會把索引持久化到日志中,重啟服務(wù)之后自增索引是不會丟失的,因此答案是 6
