自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

美團面試官:講清楚MySQL結(jié)構(gòu)體系,立馬發(fā)offer

數(shù)據(jù)庫 MySQL
今天我們就來聊聊MySQL的架構(gòu)體系,盡管咱們是Java開發(fā)人員,但是在日常開發(fā)過程中也會經(jīng)常和MySQL數(shù)據(jù)庫打交道。如果公司有DBA能干點事還稍微好點,如果是沒有DBA或者DBA沒什么卵用的情況下,我們還是很有必要了解MySQL的整個體系的,況且在面試中遇到了也是一個加分項。

[[415438]]

故事

繼續(xù)和大家分享,我去上海美團面試遇到的技術(shù)問題,當(dāng)時,回答的也是馬馬虎虎的,不能說不好,也不能說好,反正就是沒有給面試官一種爽的感覺。

害,很多東西都是,平時感覺還行,一旦到了面試的時候啥都想不起來。

雖然,本人搞Java開發(fā)快五年了(2017年),用過Oracle數(shù)據(jù)庫(銀行里的系統(tǒng)),但大多數(shù)時候都是使用MySQL數(shù)據(jù)庫,但是面對這個問題依然是一臉懵逼(硬著頭皮也扯了一些),還以為面試官要問索引、慢查詢、性能優(yōu)化之類的(因為這些都是網(wǎng)上找點面試題背過了)。

今天我們就來聊聊MySQL的架構(gòu)體系,盡管咱們是Java開發(fā)人員,但是在日常開發(fā)過程中也會經(jīng)常和MySQL數(shù)據(jù)庫打交道。如果公司有DBA能干點事還稍微好點,如果是沒有DBA或者DBA沒什么卵用的情況下,我們還是很有必要了解MySQL的整個體系的,況且在面試中遇到了也是一個加分項。

想要知道一條SQL是怎么查詢的,只要對MySQL整個體系搞清楚了,才能說出個123。

所以于情于理,我們很有必要學(xué)習(xí)一下MySQL的架構(gòu)體系的。

平時,我和小伙伴們聊天的時候,經(jīng)常會把MySQL當(dāng)做我們開發(fā)的一個軟件系統(tǒng),既然是軟件系統(tǒng),那么就有個架構(gòu)圖,以及架構(gòu)是如何分層的,每一層的功能是什么。

MySQL是什么?

  • MySQL是一個關(guān)系型數(shù)據(jù)庫管理系統(tǒng),由瑞典MySQL AB公司開發(fā),目前屬于Oracle公司。
  • MySQL是一種關(guān)聯(lián)數(shù)據(jù)庫管理系統(tǒng),將數(shù)據(jù)保存在不同的表中,而不是將所有數(shù)據(jù)放在一個大倉庫內(nèi),這樣就增加了速度并提高了靈活性。
  • MySQL是開源的,所以你不需要支付額外的費用。
  • MySQL支持大型的數(shù)據(jù)庫,可以處理擁有上千萬條記錄的大型數(shù)據(jù)庫。
  • MySQL使用標(biāo)準(zhǔn)的SQL數(shù)據(jù)語言形式。
  • MySQL可以允許于多個系統(tǒng)上,并且支持多種語言,這些編程語言包括C、C++、Python、Java、Ped、PHP、Eifel、Ruby和TCL等。
  • MySQL對PHP有很好的支持,PHP是目前最流行的Web開發(fā)語言。
  • MySQL支持大型數(shù)據(jù)庫,支持5000萬條記錄的數(shù)據(jù)倉庫,32位系統(tǒng)表文件最大可支持4GB,64位系統(tǒng)支持最大的表文件為8TB。
  • MySQL是可以定制的,采用了GPL協(xié)議,你可以修改源碼來開發(fā)自己的MySQL系統(tǒng)。

請注意MySQL拼寫,另外,很多人可能有疑問,為什么MySQL的logo是一條海豚?

下面我們就來看看MySQL的整體架構(gòu)圖。

MySQL架構(gòu)圖

再來看看我們開發(fā)的系統(tǒng)架構(gòu)圖:

其實還是蠻相似的,都有分層的概念。既然我們開發(fā)的軟件系統(tǒng)能進(jìn)行分層,那么MySQL能分層嗎?

答案是:能,下面我們就來聊聊MySQL的分層情況以及每一層的功能。

架構(gòu)圖分層

上面的架構(gòu)圖我們可以對其進(jìn)行拆分,并做簡要的說明。

連接層

與客戶端打交道,上面已經(jīng)寫明了能支持的的語言??蛻舳说逆溄又С值膮f(xié)議很多,比如我們在 Java 開發(fā)中的 JDBC。

這一層是不是有點像我們項目中的網(wǎng)關(guān)層?如果對網(wǎng)關(guān)不熟悉,那我們可以理解我controller層。

服務(wù)層

這一層,就相當(dāng)于我們業(yè)務(wù)系統(tǒng)中的service層,大雜燴,相關(guān)業(yè)務(wù)的操作、代碼優(yōu)化、緩存等都在這里面。

連接池

主要是負(fù)責(zé)存儲和管理客戶端與數(shù)據(jù)庫的鏈接,一個線程負(fù)責(zé)管理一個連接。自從引入了連接池以后,官方報道:當(dāng)數(shù)據(jù)庫的連接數(shù)達(dá)到128后,使用連接池與沒有連接池的性能是提升了n倍(反正就是性能大大的提升了)。

連接建立完成后,就可以執(zhí)行select語句了。執(zhí)行邏輯就會先來到緩存模塊。

緩存

MySQL拿到一個查詢請求后,會先到查詢緩存看看,之前是不是執(zhí)行過這條語句。之前執(zhí)行過的語句及其結(jié)果會以key-value對的形式存儲在內(nèi)存中。key是查詢的語句,value是查詢的結(jié)果。如果你的查詢能夠直接在這個緩存中找到key(命中),那么這個value就會被直接返回給客戶端。

如果在緩存中未命中,就會繼續(xù)后面的執(zhí)行階段。執(zhí)行完成后,執(zhí)行結(jié)果會被存入查詢緩存中。這里可以看到,如果查詢命中緩存,MySQL不需要執(zhí)行后面的復(fù)雜操作,就可以直接返回結(jié)果,這個效率會很高。

但是大多數(shù)情況下我會建議你不要使用查詢緩存,為什么呢?因為查詢緩存往往弊大于利。

查詢緩存的失效非常頻繁,只要有對一個表的某一條數(shù)據(jù)更新,這個表上所有的查詢緩存都會被清空。

因此可能很費勁地把結(jié)果存起來,還沒使用呢,就被一個更新全清空了。對于更新壓力大的數(shù)據(jù)庫來說,查詢緩存的命中率會非常低。除非你的業(yè)務(wù)就是有一張靜態(tài)表,很長時間才會更新一次。

比如:一個系統(tǒng)配置表,那這張表上的查詢才適合使用查詢緩存。

好在MySQL也提供了這種“按需使用”的方式。你可以將參數(shù)query_cache_type設(shè)置成DEMAND,這樣對于默認(rèn)的SQL語句都不使用查詢緩存。

「注意」:MySQL 8.0版本直接將查詢緩存的整塊功能刪掉了,標(biāo)志著MySQL8.0開始徹底沒有緩存這個功能了。

解析器

如果沒有命中查詢緩存,就要開始真正執(zhí)行語句了。首先,MySQL需要知道你要做什么,因此需要對SQL語句做解析。

分析器先會做“詞法分析”。你輸入的是由多個字符串和空格組成的一條SQL語句,MySQL需要識別出里面的字符串分別是什么,代表什么。

做完了詞法分析以后,就要做“語法分析”。根據(jù)詞法分析的結(jié)果,語法分析器會根據(jù)語法規(guī)則,判斷你輸入的這個SQL語句是否滿足MySQL語法。

如果我們在拼寫SQL時候,少了或者寫錯了某個字母,,就會收到“You have an error in your SQL syntax”的錯誤提醒。

比如下面這個案例:

錯誤在于WHERE關(guān)鍵字中差了一個E。

同樣,我們使用的SQL如果某個字段不存在。

一般語法錯誤會提示第一個出現(xiàn)錯誤的位置,所以你要關(guān)注的是緊接“use near”的內(nèi)容,僅供參考,有時候這個提示也不是非常靠譜。

經(jīng)過分析器對SQL進(jìn)行了分析,并且沒有報錯。那么此時就進(jìn)入優(yōu)化器中,對SQL進(jìn)行優(yōu)化。

優(yōu)化器

優(yōu)化器主要是在我們的數(shù)據(jù)庫表中,如果存在多個多個索引的時候,決定使用哪個索引;或者在一個語句有多表關(guān)聯(lián)(join)的時候,決定各個表的連接順序 。

比如說:

  1. 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 

它會在條件查詢上進(jìn)行優(yōu)化處理。

優(yōu)化器處理完成過后,此時就已經(jīng)確定了SQL的執(zhí)行方案。然后繼續(xù)進(jìn)入執(zhí)行器中。

執(zhí)行器

首先,肯定是要判斷權(quán)限,就是有沒有權(quán)限執(zhí)行這條SQL。工作中可能會對某些客戶端進(jìn)行權(quán)限控制。

比如說:生產(chǎn)環(huán)境中,對于大部分開發(fā)人員都只開查詢權(quán)限,沒有增刪改權(quán)限(部分小公司除外)。

如果有權(quán)限,就打開表繼續(xù)執(zhí)行。打開表的時候,執(zhí)行器就會根據(jù)表的引擎定義,去使用這個引擎提供的接口。

存儲引擎層

這一層,我們可以理解為我們業(yè)務(wù)系統(tǒng)中的持久層。

存儲引擎的概念是MySQL里面才有的,不是所有的關(guān)系型數(shù)據(jù)庫都有存儲引擎這個概念 。

數(shù)據(jù)庫存儲引擎是數(shù)據(jù)庫底層軟件組織,數(shù)據(jù)庫管理系統(tǒng)(DBMS)使用數(shù)據(jù)引擎進(jìn)行創(chuàng)建、查詢、更新和刪除數(shù)據(jù)。不同的存儲引擎提供不同的存儲機制、索引技巧、鎖定水平等功能,使用不同的存儲引擎,還可以獲得特定的功能?,F(xiàn)在許多不同的數(shù)據(jù)庫管理系統(tǒng)都支持多種不同的數(shù)據(jù)引擎。

因為在關(guān)系數(shù)據(jù)庫中數(shù)據(jù)的存儲是以表的形式存儲的,所以存儲引擎也可以稱為表類型(Table Type,即存儲和操作此表的類型)。

  • MySQL5.5版本(mysql 版本 < 5.5版本) 以前,默認(rèn)使用的存儲引擎是MyISAM 。
  • MySQL5.5版本(mysql 版本 >= 5.5版本) 以后,默認(rèn)使用的存儲引擎是InnoDB 。

下面對部分相對使用多的引擎進(jìn)行一個對比:

在實際項目中,大多數(shù)使用InnoDB,然后是MyISAM,至于其他存儲引擎使用的非常至少。

我們可以使用命令來查看MySQL 已提供什么存儲引擎 :

show engies;

也可以通過命令來查看 MySQL 當(dāng)前默認(rèn)的存儲引擎 :

show variables like '%storage_engine%';

MyISAM與 InnoDB引擎的區(qū)別

MySQL5.5 版本之前默認(rèn)的存儲引擎就是 MyISAM 存儲引擎,MySQL 中比較多的系統(tǒng)表使用 MyISAM 存儲引擎,系統(tǒng)臨時表也會用到 MyISAM 存儲引擎,但是在 Mysql5.5 之后默認(rèn)的存儲引擎就是 InnoDB 存儲引擎了。

如何在兩種存儲引擎中進(jìn)行選擇?

  • 是否有事務(wù)操作?有,InnoDB。
  • 是否存儲并發(fā)修改?有,InnoDB。
  • 是否追求快速查詢,且數(shù)據(jù)修改較少?是,MyISAM。
  • 是否使用全文索引?如果不引用第三方框架,可以選擇MyISAM,但是可以選用第三方框架和InnDB效率會更高。

InnoDB 存儲引擎主要有如下特點:

  1. 支持事務(wù)
  2. 支持 4 個級別的事務(wù)隔離
  3. 支持多版本讀
  4. 支持行級鎖
  5. 讀寫阻塞與事務(wù)隔離級別相關(guān)
  6. 支持緩存,既能緩存索引,也能緩存數(shù)據(jù)
  7. 整個表和主鍵以 Cluster 方式存儲,組成一顆平衡樹

當(dāng)然也不是說 InnoDB 一定就是好的,在實際開發(fā)中,還是要根據(jù)具體的場景來選擇到底是使用 InnoDB 還是 MyISAM 。

MyIASM(該引擎在 5.5 前的 MySQL 數(shù)據(jù)庫中為默認(rèn)存儲引擎)特點:

  1. MyISAM 沒有提供對數(shù)據(jù)庫事務(wù)的支持
  2. 不支持行級鎖和外鍵
  3. 由于 2,導(dǎo)致當(dāng)執(zhí)行 INSERT 插入或 UPDATE 更新語句時,即執(zhí)行寫操作需要鎖定整個表,所以會導(dǎo)致效率降低
  4. MyISAM 保存了表的行數(shù),當(dāng)執(zhí)行 SELECT COUNT(*) FROM TABLE 時,可以直接讀取相關(guān)值,不用全表掃描,速度快。

兩者區(qū)別:

  1. MyISAM 是非事務(wù)安全的,而 InnoDB 是事務(wù)安全的
  2. MyISAM 鎖的粒度是表級的,而 InnoDB 支持行級鎖
  3. MyISAM 支持全文類型索引,而 InnoDB 在 MySQL5.6 之前不支持全文索引,從 MySQL5.6 之后開始支持 FULLTEXT 索引了。

使用場景比較:

  1. 如果要執(zhí)行大量 select 操作,應(yīng)該選擇 MyISAM
  2. 如果要執(zhí)行大量 insert 和 update 操作,應(yīng)該選擇 InnoDB
  3. 大尺寸的數(shù)據(jù)集趨向于選擇 InnoDB 引擎,因為它支持事務(wù)處理和故障恢復(fù)。數(shù)據(jù)庫的大小決定了故障恢復(fù)的時間長短,InnoDB 可以利用事務(wù)日志進(jìn)行數(shù)據(jù)恢復(fù),這會比較快。主鍵查詢在 InnoDB 引擎下也會相當(dāng)快,不過需要注意的是如果主鍵太長也會導(dǎo)致性能問題。

相對來說,InnoDB 在互聯(lián)網(wǎng)公司使用更多一些。

系統(tǒng)文件存儲層

這一層,我們同樣的可以理解為我們業(yè)務(wù)系統(tǒng)中的數(shù)據(jù)庫。

系統(tǒng)文件存儲層主要是負(fù)責(zé)將數(shù)據(jù)庫的數(shù)據(jù)和日志存儲在系統(tǒng)的文件中,同時完成與存儲引擎的之間的打交道,是文件的物理存儲層。

比如:數(shù)據(jù)文件、日志文件、pid文件、配置文件等。

數(shù)據(jù)文件

「db.opt文件」:記錄這個數(shù)據(jù)庫的默認(rèn)使用的字符集和校驗規(guī)則。

「frm文件」:存儲于邊相關(guān)的元數(shù)據(jù)信息,包含表結(jié)構(gòu)的定義信息等,每一張表都會有一個frm文件與之對應(yīng)。

「MYD文件」:MyISAM存儲引擎專用的文件,存儲MyISAM表的數(shù)據(jù)信息,每一張MyISAM表都有有一個.MYD文件。

「MYI文件」:也是MyISAM存儲引擎專用的文件,存放MyISAM表的索引相關(guān)信息,每一張MyISAM表都有對應(yīng)的.MYI文件。

「ibd文件和ibdata文件」:存放InnoDB的數(shù)據(jù)文件(包括索引)。InnoDB存儲引擎有兩種表空間方式:獨立表空間和共享表空間。

  • 獨享表空間使用ibd文件來存放數(shù)據(jù),并且每一張InnoDB表存在與之對應(yīng)的.ibd文件。
  • 共享表空間使用ibdata文件,所有表共同使用一個或者多個.ibdata文件。

「ibdata1文件」:系統(tǒng)表空間數(shù)據(jù)文件,存儲表元數(shù)據(jù)、Undo日志等。

「ib_logfile0、ib_logfile0文件」:Redo log日志文件。

日志文件

錯誤日志:默認(rèn)是開啟狀態(tài),可以通過命令查看:

  1. show variables like '%log_error%'

二進(jìn)制日志binary log:記錄了對MySQL數(shù)據(jù)庫執(zhí)行的更改操作,并且記錄了語句的發(fā)生時間、執(zhí)行耗時;但是不記錄查詢select、show等不修改數(shù)據(jù)的SQL。主要用于數(shù)據(jù)庫恢復(fù)和數(shù)據(jù)庫主從復(fù)制。也是大家常說的binlog日志。

  1. show variables like '%log_log%';//查看是否開啟binlog日志記錄。 
  2. show variables like '%binllog%';//查看參數(shù) 
  3. show binary logs;//查看日志文件 

慢查詢?nèi)罩荆河涗洸樵償?shù)據(jù)庫超時的所有SQL,默認(rèn)是10秒。

  1. show variables like '%slow_query%';//查看是否開啟慢查詢?nèi)罩居涗洝?nbsp;
  2. show variables '%long_query_time%';//查看時長 

通用查詢?nèi)罩荆河涗浺话悴樵冋Z句;

  1. show variables like '%general%'; 

配置文件

用于存放MySQL所有的配置信息的文件,比如:my.cnf、my.ini等。

「pid文件」

pid文件是mysqld應(yīng)用程序在Linux或者Unix操作系統(tǒng)下的一個進(jìn)程文件,和許多其他Linux或者Unix服務(wù)端程序一樣,該文件放著自己的進(jìn)程id。

「socket文件」

socket文件也是Linux和Unix操作系統(tǒng)下才有的,用戶在Linux和Unix操作系統(tǒng)下客戶端連接可以不通過TCP/IP網(wǎng)絡(luò)而直接使用Unix socket來連接MySQL數(shù)據(jù)庫。

SQL查詢流程圖

總結(jié)

MySQL整個系統(tǒng)我們可以看成是我們?nèi)粘i_發(fā)的軟件系統(tǒng),也有接入層,專門對接外面客戶端的,和我們系統(tǒng)的網(wǎng)關(guān)就很像,緩存也就類似我們業(yè)務(wù)代碼中使用的緩存,解析器可以理解為業(yè)務(wù)系統(tǒng)中參數(shù)解析以及參數(shù)校驗,優(yōu)化層可以當(dāng)做我們開發(fā)代碼優(yōu)化的手段,然后存儲引擎就相當(dāng)于我們的持久層,文件系統(tǒng)相當(dāng)于整個業(yè)務(wù)系統(tǒng)中的數(shù)據(jù)庫。

可能比喻不是非常的恰當(dāng),但是希望大家能領(lǐng)略輕重的含義,目的只有一個,那就是讓大家能輕松掌握MySQL的整體情況。

本文轉(zhuǎn)載自微信公眾號「Java后端技術(shù)全棧 」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Java后端技術(shù)全棧 公眾號。

 

責(zé)任編輯:武曉燕 來源: Java后端技術(shù)全棧
相關(guān)推薦

2023-01-11 08:47:10

2023-05-22 08:17:04

2019-07-07 08:18:10

MySQL索引數(shù)據(jù)庫

2023-08-14 11:35:16

流程式轉(zhuǎn)化率數(shù)據(jù)指標(biāo)

2020-07-29 09:21:34

Docker集群部署隔離環(huán)境

2021-07-05 22:22:24

協(xié)議MQTT

2022-01-05 09:27:24

讀擴散寫擴散feed

2021-10-29 11:30:31

補碼二進(jìn)制反碼

2021-04-21 10:00:08

MySQL索引數(shù)據(jù)庫

2022-07-04 11:27:02

標(biāo)簽數(shù)據(jù)指標(biāo)標(biāo)簽體系

2024-04-01 10:09:23

AutowiredSpring容器

2019-06-20 17:49:51

RPCHTTP協(xié)議

2017-12-17 20:17:23

NoSQLSQL數(shù)據(jù)

2018-08-13 09:20:21

NoSQLSQL數(shù)據(jù)

2024-01-05 07:55:39

Linux虛擬內(nèi)存

2019-07-26 06:42:28

PG架構(gòu)數(shù)據(jù)庫

2024-05-08 00:00:00

核心線程數(shù)隊列

2018-05-21 07:08:18

行為驅(qū)動開發(fā)BDD編碼

2024-02-22 12:20:23

Linux零拷貝技術(shù)

2020-12-24 15:18:27

大數(shù)據(jù)數(shù)據(jù)分析
點贊
收藏

51CTO技術(shù)棧公眾號