版式設(shè)計(jì)網(wǎng)站優(yōu)化人員通常會(huì)將目標(biāo)關(guān)鍵詞放在網(wǎng)站首頁(yè)中的
1. 什么是Mysql?
- 我們?cè)陂_發(fā)的時(shí)候,我們都需要對(duì)業(yè)務(wù)數(shù)據(jù)進(jìn)行存儲(chǔ),這個(gè)時(shí)候,你們就會(huì)用到MySQL、Oracal等數(shù)據(jù)庫(kù)。
- MySQL它是一個(gè)關(guān)系型數(shù)據(jù)庫(kù),這種關(guān)系型數(shù)據(jù)庫(kù)就有Oracal、 MySQL,以及最近很火的PgSQL等。
那什么是關(guān)系型數(shù)據(jù)庫(kù)呢?
- 就是它是基于我們的SQL語(yǔ)句去執(zhí)行操作的。
- 其實(shí)就是關(guān)系表數(shù)據(jù)庫(kù),由表結(jié)構(gòu)來(lái)存儲(chǔ)數(shù)據(jù)與數(shù)據(jù)之間的關(guān)系,同時(shí)用SQL(Structured query language)結(jié)構(gòu)化查詢語(yǔ)句來(lái)進(jìn)行數(shù)據(jù)操作。
- 關(guān)系型數(shù)據(jù)庫(kù),對(duì)應(yīng)會(huì)有一個(gè)非關(guān)系型數(shù)據(jù)庫(kù),像我們用的比較多的?Redis 這種Key -?Value結(jié)構(gòu)數(shù)據(jù)存儲(chǔ)、hbase這種列存儲(chǔ)格式、MongoDB這種文檔存儲(chǔ)等等。
那么關(guān)系型數(shù)據(jù)庫(kù)相比非關(guān)系型數(shù)據(jù)的區(qū)別:?
- 關(guān)系型數(shù)據(jù)庫(kù)都是用表來(lái)進(jìn)行維護(hù),所以格式一致,可以統(tǒng)一用SQL語(yǔ)言來(lái)進(jìn)行操作
- 關(guān)系型數(shù)據(jù)庫(kù)都是表結(jié)構(gòu),所以靈活度不夠,操作復(fù)雜的海量數(shù)據(jù)性能比較差,所以我們才會(huì)有表結(jié)構(gòu)、索引以及索引優(yōu)化。
- 雖然性能可能會(huì)比較慢,但是能做復(fù)雜的關(guān)聯(lián)查詢操作。 比如一對(duì)一, 一對(duì)多,多對(duì)多等等。
MySQL 的優(yōu)勢(shì):
- 易用性:開發(fā)者可以在幾分鐘內(nèi)安裝好MySQL,數(shù)據(jù)庫(kù)易于管理。
- 可靠性: MySQL 是最成熟、使用最廣泛的數(shù)據(jù)庫(kù)之一。超過(guò) 25 年,它已經(jīng)在各種場(chǎng)景中進(jìn)行了測(cè)試,其中包括許多世界上最大的公司。由于MySQL 的可靠性,組織依賴 MySQL 來(lái)運(yùn)行關(guān)鍵業(yè)務(wù)應(yīng)用程序。
- 可擴(kuò)展性: MySQL 可擴(kuò)展以滿足最常訪問(wèn)的應(yīng)用程序的需求。MySQL 的本機(jī)復(fù)制架構(gòu)使 Facebook 等組織能夠擴(kuò)展應(yīng)用程序以支持?jǐn)?shù)十億用戶。
- 高性能: MySQL HeatWave比其他數(shù)據(jù)庫(kù)服務(wù)更快且成本更低,多項(xiàng)標(biāo)準(zhǔn)行業(yè)基準(zhǔn)測(cè)試證明了這一點(diǎn),包括 TPC-H、TPC-DS 和 CH-benCHmark。
- 高可用性: MySQL 為高可用性和災(zāi)難恢復(fù)提供了一套完整的本機(jī)、完全集成的復(fù)制技術(shù)。對(duì)于關(guān)鍵業(yè)務(wù)應(yīng)用程序,并滿足服務(wù)級(jí)別協(xié)議承諾,客戶可以實(shí)現(xiàn) 零數(shù)據(jù)丟失以及秒級(jí)的故障轉(zhuǎn)移恢復(fù)。
- 安全性: 數(shù)據(jù)安全需要保護(hù)和遵守行業(yè)和政府法規(guī),包括歐盟通用數(shù)據(jù)保護(hù)條例、支付卡行業(yè)數(shù)據(jù)安全標(biāo)準(zhǔn)、健康保險(xiǎn)可移植性和責(zé)任法案以及國(guó)防信息系統(tǒng)局的安全技術(shù)實(shí)施指南。MySQL 企業(yè)版提供高級(jí)安全功能,包括身份驗(yàn)證/授權(quán)、透明數(shù)據(jù)加密、審計(jì)、數(shù)據(jù)屏蔽和數(shù)據(jù)庫(kù)防火墻。
- 靈活性: MySQL 文檔存儲(chǔ)為用戶開發(fā)傳統(tǒng) SQL 和 NoSQL 無(wú)模式數(shù)據(jù)庫(kù)應(yīng)用程序提供了最大的靈活性。開發(fā)人員可以在同一個(gè)數(shù)據(jù)庫(kù)和應(yīng)用程序中混合和匹配關(guān)系數(shù)據(jù)和 JSON 文檔。
Mysql服務(wù)安裝
- 見官網(wǎng):https://dev.mysql.com/doc/refman/8.0/en/installing.html
Mysql連接或者斷開服務(wù)器?
- 官網(wǎng):https://dev.mysql.com/doc/refman/8.0/en/connecting-disconnecting.html
Mysql里面的基本庫(kù)表信息
庫(kù)基本操作
- 我們叫它數(shù)據(jù)庫(kù),數(shù)據(jù)庫(kù),所以,在表的前面還有庫(kù)的概念,操作查詢庫(kù)信息,這些基本操作就不演示了。
- 官網(wǎng):https://dev.mysql.com/doc/refman/8.0/en/database-use.html
查詢所有的庫(kù):
?
創(chuàng)建庫(kù):?
查詢當(dāng)前選擇的庫(kù):
?
表基本操作
- 官網(wǎng):MySQL :: MySQL 8.0 Reference Manual :: 13.1.20 CREATE TABLE Statement
系統(tǒng)庫(kù)表?
- 我們發(fā)現(xiàn)除了我們自己創(chuàng)建的庫(kù)以外,還有很多系統(tǒng)的庫(kù)、以及表來(lái)保證MySQL的系統(tǒng)運(yùn)行。
官網(wǎng):MySQL :: MySQL 8.0 參考手冊(cè) :: 5.3 mysql 系統(tǒng)架構(gòu)?
三個(gè)系統(tǒng)庫(kù):?
- mysql庫(kù):這一個(gè)系統(tǒng)庫(kù)是來(lái)保證我的數(shù)據(jù)庫(kù)服務(wù)正常運(yùn)行的一個(gè)系統(tǒng)表全部在這個(gè)庫(kù)里面。?
- information_schema庫(kù):包括InnoDB里面的數(shù)據(jù)、日志、事務(wù)、表;還有PROCESSLIST表:它記錄了當(dāng)前正在運(yùn)行的數(shù)據(jù)庫(kù)有多少個(gè)連接和查詢進(jìn)程的信息;ENGINES表:存儲(chǔ)引擎插件表。
- performance_schema庫(kù) - 性能庫(kù):這個(gè)庫(kù)里面所有的數(shù)據(jù)是當(dāng)前只存在內(nèi)存里面的,這個(gè)庫(kù)下面所有的事件、鎖(比如data_locks表) - 我會(huì)去鎖哪些數(shù)據(jù)。這些數(shù)據(jù)它只針對(duì)我當(dāng)前的服務(wù),如果重啟了,所有的數(shù)據(jù)會(huì)丟失,所以這個(gè)它只存在當(dāng)前內(nèi)存。
mysql系統(tǒng)庫(kù)下幾個(gè)重要的表:
- 數(shù)據(jù)字典表(Data Dictionary Tables)
- 授權(quán)表(Grant System Tables)
- 對(duì)象信息表(Object Information System Tables):plugin 插件注冊(cè)表 等待
- 日志系統(tǒng)表(Log System Tables):
- general_log:一般查詢?nèi)罩颈怼?
- slow_log:慢查詢?nèi)罩颈怼?
日志配置:
show variables like 'general_log'; //一般查詢?nèi)罩?#xff0c;默認(rèn)關(guān)閉
SELECT @@long_query_time;
show global variables like 'long_query_time';
show global variables like 'min_examined_row_limit'; //至少需要檢索這么多行
show global variables like 'slow_query_log'; //是否開啟慢日志查詢 默認(rèn)關(guān)閉
SET GLOBAL slow_query_log=1;
set global long_query_time=0.1; //超過(guò)100毫秒
log_output=table |file |none //設(shè)置是放在文件中,還是在mysql.slow_log表中
Sql語(yǔ)句的執(zhí)行流程
- 客戶端發(fā)送一條語(yǔ)句給到服務(wù)器,然后服務(wù)器它能給你一個(gè)它的數(shù)據(jù)。
一.?跟服務(wù)器建立連接:
- 只有建立連接以后,我才能夠發(fā)送SQL語(yǔ)句給到服務(wù)器,服務(wù)器它才能夠去進(jìn)行接收,這樣才能進(jìn)行網(wǎng)絡(luò)IO。
連接管理
- 首先,我們得有連接,那么Mysql里面就有一個(gè)連接層,來(lái)管理連接,我們看下跟連接有關(guān)的變量/參數(shù)
- 變量:隨著我的服務(wù)的運(yùn)行,它會(huì)變更的,這些變量會(huì)隨著我的客戶端連接的變多而變多。?
MySQL的四個(gè)線程狀態(tài)變量:MySQL :: MySQL 8.0 參考手冊(cè) :: 5.1.6 服務(wù)器狀態(tài)變量參考
- Thread_cached:是MySQL的一個(gè)狀態(tài)變量,表示MySQL線程緩存中當(dāng)前緩存的線程數(shù),是為了我的服務(wù),不用每一次客戶端建立連接的時(shí)候都去創(chuàng)建一個(gè)線程,以此減少線程的創(chuàng)建和銷毀的開銷,提高數(shù)據(jù)庫(kù)性能,所以它有一個(gè)緩存的線程數(shù)。當(dāng)一個(gè)客戶端連接到MySQL數(shù)據(jù)庫(kù)服務(wù)器時(shí),服務(wù)器會(huì)為該連接創(chuàng)建一個(gè)線程來(lái)處理客戶端的請(qǐng)求。線程緩存的作用就是在該連接請(qǐng)求結(jié)束后,將這些線程緩存在內(nèi)存中,以便下次有新的連接請(qǐng)求時(shí)能夠復(fù)用這些線程,而不需要重新創(chuàng)建。thread_cache_size是MySQL的一個(gè)靜態(tài)配置參數(shù),用來(lái)配置線程緩存的大小,默認(rèn)是-1,需要手動(dòng)調(diào)整(在MySQL配置文件當(dāng)中配置)并重啟MySQL服務(wù)才能生效,最大是16384。
- Thread_connected:我當(dāng)前打開的線程數(shù),就是我現(xiàn)在有多少個(gè)線程是打開的。
- Thread_created:總共創(chuàng)建的線程數(shù),即創(chuàng)建的線程總數(shù)。創(chuàng)建的線程總數(shù)越多,我們的thread_cache_size 可以對(duì)應(yīng)的更大,來(lái)提升線程的緩存命中率。
- Threads_running:正在運(yùn)行的線程數(shù)
-- 查看MySQL的四個(gè)Thread線程狀態(tài)變量
show status like 'Thread%';
-- 查詢thread_cache_size系統(tǒng)變量
select @@thread_cache_size;
查看當(dāng)前正在運(yùn)行的線程:
-- 顯示當(dāng)前正在運(yùn)行的線程
show full PROCESSLIST;
該查詢將返回一個(gè)結(jié)果集,包含所有當(dāng)前連接的信息。每一行代表一個(gè)連接,每個(gè)連接的信息包括
id:線程 ID
State:連接狀態(tài)
User:操作的用戶名
Host:主機(jī) / IP
db:操作的數(shù)據(jù)庫(kù)
command:當(dāng)前連接執(zhí)行的命令:Sleep-休眠、Query-查詢
Time:這個(gè)狀態(tài)持續(xù)的時(shí)間,單位是s
info - 信息:查詢會(huì)有查詢的信息,但是長(zhǎng)度有限制,可能不全
刪除阻塞線程
- 官網(wǎng):https://dev.mysql.com/doc/refman/8.0/en/kill.html
使用PROCESSLIST表可以查看當(dāng)前正在運(yùn)行的連接-線程,假如當(dāng)前有客戶端連接已經(jīng)阻塞了,那么此時(shí)你可以去把它KILL掉:
demo
SELECT * FROM product_new --表中有500W數(shù)據(jù),查詢很慢
2. 會(huì)話二:
SHOW PROCESSLIST; -- 查看當(dāng)前線程
執(zhí)行結(jié)果:
3. 關(guān)閉查詢query:
???????KILL QUERY 9328; -- 終止查詢?
4. 殺死 / 關(guān)閉連接線程 - Connection Thread??
KILL 2280; -- kill 連接線程
查看會(huì)話一的結(jié)果:
- [Err] - Lost connection to MySQL server during query - 丟失連接Connection?
其他連接相關(guān)配置參數(shù):
show status like 'Max_used_connections%';
?
- Max_used_connections 自服務(wù)啟動(dòng)以來(lái)最大的連接數(shù)
- Max_used_connections_time 達(dá)到這個(gè)峰值的時(shí)間
幾個(gè)全局系統(tǒng)變量:?
-- 查詢最大連接數(shù) 默認(rèn)151
SELECT @@max_connections;
select @@GLOBAL.max_connections;-- 手動(dòng)設(shè)置最大連接數(shù)
SET @@GLOBAL.max_connections = 1000;-- 查詢服務(wù)器超時(shí)等待時(shí)間 默認(rèn)28800s - 8h
SELECT @@wait_timeout;
select @@GLOBAL.wait_timeout;-- 手動(dòng)設(shè)置服務(wù)器最大等待時(shí)間
SET @@GLOBAL.wait_timeout = 1000;
- max_connections:最大的連接數(shù),即我的服務(wù)最多能開啟的連接數(shù),超過(guò)該值不允許建立連接,默認(rèn)151,最小1,最大 100000。如果開啟太大,同時(shí)會(huì)有很多的客戶端來(lái)進(jìn)行連接操作,MySQL性能可能會(huì)跟不上;如果開啟太小,可能在高并發(fā)場(chǎng)景下導(dǎo)致并發(fā)量上不來(lái)。
- wait_timeout:最大的等待時(shí)間 / 服務(wù)器超時(shí)等待時(shí)間 / 非交互連接等待的時(shí)間(單位s),默認(rèn)28800s,也就是8小時(shí),用于指定一個(gè)連接在空閑狀態(tài)下的最長(zhǎng)等待時(shí)間。如果一個(gè)連接在8小時(shí)內(nèi)沒有進(jìn)行任何操作,那么MySQL服務(wù)器會(huì)自動(dòng)關(guān)閉該連接,以釋放資源。wait_timeout??=> 服務(wù)器什么時(shí)候會(huì)自動(dòng)關(guān)閉?
跟服務(wù)器建立完連接之后,此時(shí)就代表客戶端能跟服務(wù)端去進(jìn)行通信了,也就是客戶端能向服務(wù)端去發(fā)送SQL語(yǔ)句的請(qǐng)求了。?
MySQL Server中的第一層 - 網(wǎng)絡(luò)連接層
二. 解析器
- 當(dāng)建立連接后,客戶端向服務(wù)端去發(fā)送SQL語(yǔ)句請(qǐng)求時(shí)需要解析SQL語(yǔ)句,會(huì)把一條SQL語(yǔ)句解析生成語(yǔ)法樹;因?yàn)?/span>MySQL不是人,不會(huì)一眼看到SQL語(yǔ)句就知道要做什么事情。
- 所以它會(huì)借用解析器去把SQL語(yǔ)句解析出來(lái),看是否符合我們的SQL語(yǔ)法,最終生成一個(gè)語(yǔ)法樹(理解為一個(gè)數(shù)據(jù)結(jié)構(gòu))。
解析器分為詞法解析跟語(yǔ)法解析!
詞法解析(器)
- 將SQL語(yǔ)句打碎,轉(zhuǎn)化成一個(gè)一個(gè)關(guān)鍵單詞 =>?然后交給語(yǔ)法解析器去構(gòu)建語(yǔ)法樹,判斷語(yǔ)法是否正確
語(yǔ)法解析(器) ?
- 語(yǔ)法解析已經(jīng)知道每個(gè)SQL語(yǔ)句的單詞了,那么在語(yǔ)法解析的時(shí)候,會(huì)去構(gòu)建語(yǔ)法樹,接著會(huì)去判斷 / 檢查語(yǔ)法是否正確,比如,where是不是寫出where1,from寫成from1;
- 表名、列名是否存在、用戶是否有操作權(quán)限等等。
- 如果發(fā)現(xiàn)語(yǔ)法錯(cuò)誤,則MySQL直接拋出相應(yīng)的錯(cuò)誤信息,并拒絕執(zhí)行該SQL語(yǔ)句。
總結(jié):
- 先將輸入的SQL語(yǔ)句解析為語(yǔ)法樹,然后對(duì)語(yǔ)法樹進(jìn)行語(yǔ)法檢查,這樣可以確保在執(zhí)行之前先判斷SQL語(yǔ)句是否符合MySQL的語(yǔ)法規(guī)則,避免執(zhí)行無(wú)效或錯(cuò)誤的語(yǔ)句。?
三. 預(yù)處理器 / 預(yù)編譯器(可做可不做) ?
預(yù)處理 / 預(yù)編譯的兩個(gè)作用:?
- 提升性能
- 防止SQL注入,更安全?
MyBatis中的SQL注入是MyBatis去做的參數(shù)化,而這里的SQL注入是我們的MySQL服務(wù)器自己能支持的,預(yù)處理器它是我們的MySQL服務(wù)能支撐的。?
什么是預(yù)處理?
- 以我們的工作場(chǎng)景為例,一個(gè)查詢接口,SQL語(yǔ)句都是一樣的,但是每次查詢的參數(shù)都不一樣,所以我們想只需要變更參數(shù)部分就行。
- 那么,我們就是在拼接SQL語(yǔ)句的時(shí)候,將用戶的輸入跟語(yǔ)句拼接成一個(gè)SQL語(yǔ)句給到MySQL執(zhí)行。
- 但是會(huì)發(fā)生一個(gè)SQL注入問(wèn)題!
什么是SQL注入?
- 因?yàn)閰?shù)是客戶端傳過(guò)來(lái)的,所以可以傳任何值,那么就有可能傳入任何值就有了SQL注入問(wèn)題。
-- 要執(zhí)行的SQL語(yǔ)句
select * from emp where password = '';-- SQL注入演示-客戶端傳入查詢的參數(shù)為: ' or '1' = '1
select * from emp where password = '' or '1' = '1';
那么能不能把這個(gè)參數(shù)化的事情交給MySQL自己做呢?
- 當(dāng)然可以,這個(gè)就是預(yù)處理。
- 如果你需要參數(shù)化,你只要告訴MySQL,傳一個(gè)預(yù)處理語(yǔ)句就行,MySQL會(huì)將參數(shù)與語(yǔ)句編譯分開。
預(yù)處理操作解決SQL注入
預(yù)處理語(yǔ)句的工作流程 / 預(yù)處理語(yǔ)句為什么能夠防止SQL注入?
- 首先在應(yīng)用程序中,應(yīng)該去創(chuàng)建一個(gè)預(yù)處理語(yǔ)句,將SQL查詢與占位符(通常使用問(wèn)號(hào)?來(lái)表示)組合起來(lái),形成一個(gè)帶有參數(shù)占位符的SQL查詢語(yǔ)句。
- 接著,應(yīng)用程序?qū)⑦@個(gè)預(yù)處理語(yǔ)句發(fā)送到MySQL服務(wù)器進(jìn)行編譯。服務(wù)器會(huì)對(duì)SQL語(yǔ)句進(jìn)行語(yǔ)法解析和執(zhí)行計(jì)劃生成,但不會(huì)執(zhí)行實(shí)際的查詢。
- 在執(zhí)行查詢之前,應(yīng)用程序通過(guò)綁定參數(shù)的方式將實(shí)際的參數(shù)值與占位符關(guān)聯(lián)起來(lái),這樣可以防止SQL注入攻擊,因?yàn)橛脩糨斎氲膮?shù)不會(huì)直接嵌入到查詢語(yǔ)句中,而是作為參數(shù)傳遞給服務(wù)器,并允許在多次執(zhí)行中重復(fù)使用預(yù)處理語(yǔ)句(因?yàn)轭A(yù)處理語(yǔ)句只需編譯一次,再次執(zhí)行時(shí)就無(wú)需重新編譯,以此提高性能)。
- 一旦參數(shù)綁定完成,應(yīng)用程序可以多次執(zhí)行相同的預(yù)處理語(yǔ)句,通過(guò)更改參數(shù)值來(lái)獲取不同的結(jié)果。
預(yù)處理Demo,防止SQL注入:?
-- 創(chuàng)建預(yù)處理語(yǔ)句
-- PREPARE 預(yù)處理名字 from 'SQL語(yǔ)句';
PREPARE select_user from 'select * from emp where password = ?'-- 綁定參數(shù)(設(shè)置參數(shù)值)
SET @passsword = '123456';-- 執(zhí)行預(yù)處理語(yǔ)句
-- EXECUTE 預(yù)處理名字 USING @綁定參數(shù)名;
EXECUTE select_user USING @passsword;-- 清除預(yù)處理語(yǔ)句
-- DEALLOCATE PREPARE 預(yù)處理名字;
DEALLOCATE PREPARE select_user;
預(yù)處理主要做主要做以下2個(gè)事情:
- 將語(yǔ)句編譯、優(yōu)化跟參數(shù)分開處理,當(dāng)執(zhí)行SQL語(yǔ)句相同,參數(shù)不同的場(chǎng)景,提升性能。
- 因?yàn)槭菂?shù)化去執(zhí)行的,而不是拼接參數(shù),從而解決了SQL注入問(wèn)題。
比如我們經(jīng)常被問(wèn)的Mybatis里面#跟$符號(hào)的區(qū)別:
- #符號(hào)執(zhí)行SQL時(shí),會(huì)將#{...}替換成?,生成預(yù)編譯SQL / 預(yù)處理SQL,然后進(jìn)行預(yù)處理,能防止SQL注入,并且必須傳入?yún)?shù);
- $符號(hào)會(huì)拼接SQL,直接將${...}參數(shù)拼接在SQL語(yǔ)句中,存在SQL注入問(wèn)題。
四. 優(yōu)化器 - 決定怎么做?
- 根據(jù)上面的流程,我們知道要去執(zhí)行什么語(yǔ)句,但是具體怎么執(zhí)行會(huì)有很多的方式,比如走哪個(gè)索引,要不要回表,要不要去在內(nèi)存里面排序,你的語(yǔ)句是不是可以優(yōu)化等等。
-- 獲取MySQL數(shù)據(jù)庫(kù)中的全局優(yōu)化器開關(guān)配置信息
SELECT @@GLOBAL.optimizer_switch;
- 優(yōu)化器說(shuō)明:https://dev.mysql.com/doc/refman/8.0/en/optimizer-hints.html,里面包含了每個(gè)優(yōu)化選項(xiàng)說(shuō)明.
- 優(yōu)化方式官網(wǎng)地址:https://dev.mysql.com/doc/refman/8.0/en/optimization.html;這個(gè)里面就有很多優(yōu)化器的實(shí)踐,比如優(yōu)化sql語(yǔ)句等等。
- 優(yōu)化器它是基于服務(wù),覺得自己最快的一些方式去執(zhí)行這個(gè)語(yǔ)句,優(yōu)化后會(huì)生成一個(gè)最優(yōu)的執(zhí)行計(jì)劃,并將該執(zhí)行計(jì)劃傳遞給存儲(chǔ)引擎層,所以這個(gè)語(yǔ)句到底怎么走,優(yōu)化器來(lái)決定。
- 它是基于內(nèi)存與CPU或性能的消耗得到一個(gè)算法或者說(shuō)得到哪一個(gè)執(zhí)行計(jì)劃它是最快的。
- 當(dāng)前,優(yōu)化器里面有一些東西它是可以自己設(shè)置的,比如說(shuō)要不要索引下推,比如說(shuō)要不要回表,比如說(shuō)要不要去用聯(lián)合索引,要不要用hash_join,要不要用跳躍掃描skip_scan,要不要用mrr,mrr是它底層的一個(gè)算法,能夠更快的跟我的磁盤去進(jìn)行交互等等。?
MySQL? Server中的第二層 - 核心服務(wù)層,核心服務(wù)層不牽扯到數(shù)據(jù)的存儲(chǔ)與查詢。
五. 執(zhí)行器?- 去操作數(shù)據(jù)的
- 根據(jù)執(zhí)行計(jì)劃,去調(diào)用數(shù)據(jù)存儲(chǔ)的地方,也就來(lái)到了我們MySQL Server中的第三層 - 存儲(chǔ)引擎層!
剛剛講了 MySQL的很多插件 , 但是還沒有真正的去跟數(shù)據(jù)交互 ,也就是沒有去查詢數(shù)據(jù)。 數(shù)據(jù)是放在我們的MySQL Server中的存儲(chǔ)引擎層。- 存儲(chǔ)引擎層是真正的跟數(shù)據(jù)進(jìn)行交互的,是真正的來(lái)保存以及怎么去查詢數(shù)據(jù)的,所以存儲(chǔ)引擎層決定了我這個(gè)數(shù)據(jù)以什么樣子的方式來(lái)保存,比如說(shuō)你是保存到磁盤,還是保存到內(nèi)存,還是磁盤跟內(nèi)存都有。?
- 執(zhí)行器去根據(jù)表設(shè)置的存儲(chǔ)引擎,調(diào)用不同存儲(chǔ)引擎的API接口獲取數(shù)據(jù)。?
- 至于這個(gè)數(shù)據(jù)是怎么存的,這個(gè)數(shù)據(jù)有哪些優(yōu)化(比如內(nèi)存去緩存)等等,就是每個(gè)存儲(chǔ)引擎自己去做的事情,也就來(lái)到了我們MySQL Server中的第三層中的存儲(chǔ)引擎層,并且存儲(chǔ)引擎是跟MySQL解耦的,存儲(chǔ)引擎跟MySQL的開發(fā)者都不是同一批人。
- 存儲(chǔ)引擎它是我們MySQL的一個(gè)插件,你如果有能力,MySQL都支持你自己寫存儲(chǔ)引擎。
- 基于不同的一些場(chǎng)景,比如說(shuō)有一些場(chǎng)景我要去保證性能,有一些場(chǎng)景我要去保證一致性,所以它會(huì)有不同的存儲(chǔ)方案,這里就牽扯到我們不同的存儲(chǔ)引擎。
MySQL支持不同的存儲(chǔ)引擎,這些存儲(chǔ)引擎決定了我們數(shù)據(jù)的存儲(chǔ)方式,以及數(shù)據(jù)的可靠性、一致性、持久性、原子性。也就是我們經(jīng)常講的ACID。
那么官網(wǎng)提供了哪些存儲(chǔ)引擎?
- 官網(wǎng):MySQL :: MySQL 8.0 Reference Manual :: 16 Alternative Storage Engines
可以通過(guò)語(yǔ)句查詢當(dāng)前服務(wù)器支持哪些存儲(chǔ)引擎: ?
SHOW ENGINES; -- 查詢當(dāng)前服務(wù)器支持的存儲(chǔ)引擎
InnoDB
- MySQL 8.0默認(rèn)的存儲(chǔ)引擎。InnoDB是一個(gè)事務(wù)安全(兼容ACID) 的MySQL存儲(chǔ)引擎,具有提交、回滾和崩潰恢復(fù)功能,以保護(hù)用戶數(shù)據(jù)。
- InnoDB支持行級(jí)別的鎖(沒有升級(jí)到更粗粒度的鎖)和Oracle風(fēng)格一致的非鎖讀取提高了多用戶并發(fā)性和性能。
- InnoDB將用戶數(shù)據(jù)存儲(chǔ)在聚集索引中,以減少常見的基于主鍵的查詢的I/O。
- 為了維護(hù)數(shù)據(jù)的完整性,InnoDB還支持外鍵引用完整性約束。
MyISAM
- 這些表占用空間很小。
- 表級(jí)鎖限制了讀/寫工作負(fù)載的性能,因此它經(jīng)常用于Web和數(shù)據(jù)倉(cāng)庫(kù)配置中的只讀或以讀為主的工作負(fù)載中,所以它的性能要比InnoDB要高。
Memory
- Memory它只是把數(shù)據(jù)存儲(chǔ)在內(nèi)存,它不會(huì)做持久化。?
不同的存儲(chǔ)引擎會(huì)有自己不同的存儲(chǔ)實(shí)現(xiàn)方式 / 存儲(chǔ)方案,不管是什么存儲(chǔ)引擎,它一定要做的事情是把這個(gè)數(shù)據(jù)保存起來(lái),是用內(nèi)存還是磁盤,還是都用,或者磁盤的文件格式等等都會(huì)不一樣。
- 既然要保存,那么就一定要有個(gè)數(shù)據(jù)的目錄,這個(gè)目錄,也就是我們的一個(gè)變量,這個(gè)變量就是代表你保存到哪里。
接下來(lái)我們看下數(shù)據(jù)到底存儲(chǔ)在哪里,以什么樣的方式存儲(chǔ)?
數(shù)據(jù)存儲(chǔ)地址?
SQL語(yǔ)句查詢:
-- 查詢數(shù)據(jù)庫(kù)的數(shù)據(jù)目錄
select @@datadir;
show variables like '%datadir%';
該目錄就是我們的數(shù)據(jù)庫(kù)的數(shù)據(jù)目錄,我們的數(shù)據(jù)保存在該目錄下。??