關注「Java後端技術全棧」java
回覆「面試」獲取全套面試資料mysql
字數:3620,閱讀耗時:4分35秒面試
最近羣裏一位兄弟在面試中被問到:「MySQL的架構體系是什麼」。sql
雖然他搞java開發好幾年了,也一直使用的是MySQL數據庫,可是面對這個問題依然是一臉懵逼,還覺得面試官要問索引、慢查詢、性能優化之類的(由於這些都是網上找點面試題背過了)。數據庫
但這位面試官不按套路出牌,這位兄弟當場就是臉紅耳赤的,心想nnd竟然會這麼問。其實面試中面試官的問題有千千萬,有的問題確實背背面試題就能應對,但不是全部的面試題我們都能背下來的。後端
今天咱們就來聊聊MySQL的架構體系,儘管我們是java開發人員,可是在平常開發過程當中也會常常和MySQL數據庫打交道。若是公司有DBA能幹點事還稍微好點,若是是沒有DBA或者DBA沒什麼卵用的狀況下,咱們仍是頗有必要了解MySQL的整個體系的,何況在面試中遇到了也是一個加分項。緩存
想要知道一條SQL是怎麼查詢的,只要對MySQL整個體系搞清楚了,才能說出個123。性能優化
因此於情於理,咱們頗有必要學習一下MySQL的架構體系的。網絡
平時,和小夥伴們聊天的時候,常常會把MySQL當作咱們開發的一個軟件系統,既然是軟件系統,那麼就有個架構圖,以及架構是如何分層的,每一層的功能是什麼。多線程
下面咱們就來看看MySQL的總體架構圖。
再來看看咱們開發的系統架構圖:
其實仍是蠻類似的。都有分層的概念。既然咱們開發的軟件系統能進行分層,那麼MySQL能分層嗎?
答案是:能,下面咱們就來聊聊MySQL的分層狀況以及每一層的功能。
上面的架構圖咱們能夠對其進行拆分,並作簡要的說明。
與客戶端打交道,上面已經寫明瞭能支持的的語言。客戶端的連接支持的協議不少,好比咱們在 Java 開發中的 JDBC。
主要是負責存儲和管理客戶端與數據庫的連接,一個線程負責管理一個鏈接。自從引入了鏈接池之後,官方報道:當數據庫的鏈接數達到128後,使用鏈接池與沒有鏈接池的性能是提高了n倍(反正就是性能大大的提高了)。
鏈接創建完成後,就能夠執行select語句了。執行邏輯就會先來到緩存模塊。
MySQL拿到一個查詢請求後,會先到查詢緩存看看,以前是否是執行過這條語句。以前執行過的語句及其結果會以key-value對的形式存儲在內存中。key是查詢的語句,value是查詢的結果。若是你的查詢可以直接在這個緩存中找到key(命中),那麼這個value就會被直接返回給客戶端。
若是在緩存中未命中,就會繼續後面的執行階段。執行完成後,執行結果會被存入查詢緩存中。這裏能夠看到,若是查詢命中緩存,MySQL不須要執行後面的複雜操做,就能夠直接返回結果,這個效率會很高。
可是大多數狀況下我會建議你不要使用查詢緩存,爲何呢?由於查詢緩存每每弊大於利。
查詢緩存的失效很是頻繁,只要有對一個表的某一條數據更新,這個表上全部的查詢緩存都會被清空。
所以可能很費勁地把結果存起來,還沒使用呢,就被一個更新全清空了。對於更新壓力大的數據庫來講,查詢緩存的命中率會很是低。除非你的業務就是有一張靜態表,很長時間纔會更新一次。
好比:一個系統配置表,那這張表上的查詢才適合使用查詢緩存。
好在MySQL也提供了這種「按需使用」的方式。你能夠將參數query_cache_type設置成DEMAND,這樣對於默認的SQL語句都不使用查詢緩存。
「注意」:MySQL 8.0版本直接將查詢緩存的整塊功能刪掉了,標誌着MySQL8.0開始完全沒有緩存這個功能了。
若是沒有命中查詢緩存,就要開始真正執行語句了。首先,MySQL須要知道你要作什麼,所以須要對SQL語句作解析。
分析器先會作「詞法分析」。你輸入的是由多個字符串和空格組成的一條SQL語句,MySQL須要識別出裏面的字符串分別是什麼,表明什麼。
作完了詞法分析之後,就要作「語法分析」。根據詞法分析的結果,語法分析器會根據語法規則,判斷你輸入的這個SQL語句是否知足MySQL語法。
若是咱們在拼寫SQL時候,少了或者寫錯了某個字母,,就會收到「You have an error in your SQL syntax」的錯誤提醒。
好比下面這個案例:
錯誤在於WHERE關鍵字中差了一個E。
一樣,咱們使用的SQL若是某個字段不存在。
通常語法錯誤會提示第一個出現錯誤的位置,因此你要關注的是緊接「use near」的內容,僅供參考,有時候這個提示也不是很是靠譜。
通過分析器對SQL進行了分析,而且沒有報錯。那麼此時就進入優化器中,對SQL進行優化。
優化器主要是在咱們的數據庫表中,若是存在多個多個索引的時候,決定使用哪一個索引;或者在一個語句有多表關聯(join)的時候,決定各個表的鏈接順序 。
好比說:
SELECT a.id, b.id FROM t_user a join t_user_detail b WHERE a.id=b.user_id and a.user_name='田維常' and b.id=10001
它會在條件查詢上進行優化處理。
優化器處理完成事後,此時就已經肯定了SQL的執行方案。而後繼續進入執行器中。
首先,確定是要判斷權限,就是有沒有權限執行這條SQL。工做中可能會對某些客戶端進行權限控制。
好比說:生產環境中,對於大部分開發人員都只開查詢權限,沒有增刪改權限(部分小公司除外)。
若是有權限,就打開表繼續執行。打開表的時候,執行器就會根據表的引擎定義,去使用這個引擎提供的接口。
存儲引擎的概念是MySQL裏面纔有的,不是全部的關係型數據庫都有存儲引擎這個概念 。
數據庫存儲引擎是數據庫底層軟件組織,數據庫管理系統(DBMS)使用數據引擎進行建立、查詢、更新和刪除數據。不一樣的存儲引擎提供不一樣的存儲機制、索引技巧、鎖定水平等功能,使用不一樣的存儲引擎,還能夠得到特定的功能。如今許多不一樣的數據庫管理系統都支持多種不一樣的數據引擎。
由於在關係數據庫中數據的存儲是以表的形式存儲的,因此存儲引擎也能夠稱爲表類型(Table Type,即存儲和操做此表的類型)。
下面對部分相對使用多的引擎進行一個對比:
在實際項目中,大多數使用InnoDB,而後是MyISAM,至於其餘存儲引擎使用的很是至少。
Mysql5.5 版本以前默認的存儲引擎就是 MyISAM 存儲引擎,MySQL 中比較多的系統表使用 MyISAM 存儲引擎,系統臨時表也會用到 MyISAM 存儲引擎,可是在 Mysql5.5 以後默認的存儲引擎就是 InnoDB 存儲引擎了。
兩個主要緣由:
系統文件存儲層主要是負責將數據庫的數據和日誌存儲在系統的文件中,同時完成與存儲引擎的之間的打交道,是文件的物理存儲層。
好比:數據文件、日誌文件、pid文件、配置文件等。
「db.opt文件」:記錄這個數據庫的默認使用的字符集和校驗規則。
「frm文件」:存儲於邊相關的元數據信息,包含表結構的定義信息等,每一張表都會有一個frm文件與之對應。
「MYD文件」:MyISAM存儲引擎專用的文件,存儲MyISAM表的數據信息,每一張MyISAM表都有有一個.MYD文件。
「MYI文件」:也是MyISAM存儲引擎專用的文件,存放MyISAM表的索引相關信息,每一張MyISAM表都有對應的.MYI文件。
「ibd文件和ibdata文件」:存放InnoDB的數據文件(包括索引)。InnoDB存儲引擎有兩種表空間方式:獨立表空間和共享表空間。
「ibdata1文件」:系統表空間數據文件,存儲表元數據、Undo日誌等。
「ib_logfile0、ib_logfile0文件」:Redo log日誌文件。
錯誤日誌:默認是開啓狀態,能夠經過命令查看:
show variables like '%log_error%';
二進制日誌binary log:記錄了對MySQL數據庫執行的更改操做,而且記錄了語句的發生時間、執行耗時;可是不記錄查詢select、show等不修改數據的SQL。主要用於數據庫恢復和數據庫主從複製。也是你們常說的binlog日誌。
show variables like '%log_log%';//查看是否開啓binlog日誌記錄。 show variables like '%binllog%';//查看參數 show binary logs;//查看日誌文件
慢查詢日誌:記錄查詢數據庫超時的全部SQL,默認是10秒。
show variables like '%slow_query%';//查看是否開啓慢查詢日誌記錄。 show variables '%long_query_time%';//查看時長
通用查詢日誌:記錄通常查詢語句;
show variables like '%general%';
用於存放MySQL全部的配置信息的文件,好比:my.cnf、my.ini等。
「pid文件」
pid文件是mysqld應用程序在Linux或者Unix操做系統下的一個進程文件,和許多其餘Linux或者Unix服務端程序同樣,該文件放着本身的進程id。
「socket文件」
socket文件也是Linux和Unix操做系統下才有的,用戶在Linux和Unix操做系統下客戶端鏈接能夠不經過TCP/IP網絡而直接使用Unix socket來鏈接MySQL數據庫。
SQL查詢流程圖
MySQL整個系統咱們能夠當作是咱們平常開發的軟件系統,也有接入層,專門對接外面客戶端的,和咱們系統的網關就很像,緩存也就相似咱們業務代碼中使用的緩存,解析器能夠理解爲業務系統中參數解析以及參數校驗,優化層能夠當作咱們開發代碼優化的手段,而後存儲引擎就至關於咱們的持久層,文件系統至關於整個業務系統中的數據庫。
可能比喻不是很是的恰當,可是但願你們能領略輕重的含義,目的只有一個,那就是讓你們能輕鬆掌握MySQL的總體狀況。
不要每天羨慕什麼大牛,什麼大神,他們也是一步一步來的(個例除外)。自信點,只要你一點一點搞,踏踏實實的幹,你也會成爲大神的。
文中圖片來源於網絡,侵刪!
推薦閱讀