1. 程式人生 > 其它 >字串存入mysql_MySQL 學習筆記 (1): MySQL 基礎架構

字串存入mysql_MySQL 學習筆記 (1): MySQL 基礎架構

技術標籤:字串存入mysql

MySQL 包含 Server 層和儲存引擎層。Server 層中有聯結器查詢快取分析器優化器執行器等;儲存引擎負責資料的儲存提取,其架構時外掛式的,支援 InnoDB、MyISAM、Memory 等多個儲存引擎。在 5.5.5 版本後,MySQL 預設的儲存引擎就是 InnoDB, 也就是說假如建表的時候不指定儲存引擎,那麼就會使用 InnoDB.

下面通過一條 SQL 語句來具體解釋各個部件的作用:select * from t where id = 1; 聯結器當在終端、命令列、powershell 中輸入連線命令按下 “Enter” 時,MySQL 處理連線資訊的就是聯結器。聯結器負責與客戶端建立連線、獲取許可權、維持和管理連線。連線的命令通常是: mysql -h localhost -u root -p -P 3306.-h 引數指定的是資料庫地址,如果是在本地填寫 localhost 即可;若是遠端連線伺服器上安裝的 MySQL,就填寫伺服器的公網 IP 地址。-u 引數用來指定連線的使用者。-P 用來指定連線的埠,如果是連線本地的資料庫,那麼就不需要這個埠,我填寫的 3306 是連線雲伺服器上的 MySQL 時使用的埠,不過在此之前要在雲伺服器的安全組中開放這個埠。-p 就是輸入密碼的引數,不過密碼不必在命令中輸入,空著就行。按下 “Enter” 後會提示輸入密碼,此時密碼就是用 * 代替。經過 TCP 握手後,聯結器開始認證使用者身份,此時需要使用輸入的使用者名稱和密碼。若使用者名稱或密碼不正確,就會提示 "Access denied for user xxx" 的資訊。認證通過後,聯結器會到許可權表裡查詢使用者擁有的許可權,之後連線裡面是許可權判斷邏輯,都將依賴於此時讀取到的許可權。所以某個使用者建立連線後,即便使用 root 使用者對其許可權進行修改,也不會影響已經存在連線的許可權。連線完成後,如果沒有其他操作,此連線就處於空閒狀態,使用如下命令
show processlist
可以看到連線情況,表格中 command 列顯示 sleep 就表示有個空閒連線:

41e06d2d75622ab30f8e9858546b4d82.png

假如客戶端長時間沒有執行命令,聯結器就會自動將其斷開。這個時間是由引數 wait_timeout 控制的,預設是 8 小時。假如連線被斷開之後,客戶端再次傳送命令,就會收到錯誤提醒:“Lost connection to MySQL server furing query”, 只要重新連線就可以繼續執行命令。 聯結器的分類建立的連線分為 長連線短連線。長連線是指連線成功後,如果客戶端持續有請求,則一直使用同一個連線。短連線是指每次執行完很少的幾次查詢就斷開連線,下次查詢時再重新建立一個。建立連線的過程比較複雜,所以建議在使用中儘量減少建立連線的動作,也就是儘量使用長連線但是全部使用長連線後,有時 MySQL 記憶體佔用會變得很多而且漲幅很大,這是因為 MySQL 在執行過程中臨時使用的記憶體是管理在連線物件裡面的,這些資源在連線斷開的時候才會被釋放。所以如果有很多的長連線累計,就會導致佔用的記憶體過多,被系統強行關閉,如此看來就是 MySQL 異常重啟解決這個問題有兩種辦法:
  • 定期斷開長連線。使用一段時間或者程式裡面執行過一個佔用記憶體的大查詢後,斷開連線,之後查詢時再連

  • 如果使用的是 5.7 及更新版本,可以再每次執行一個比較大的操作後,通過執行 mysql_reset_connection 來重新初始化連線資源。此過程不需要重連、重新驗證許可權,但是可以將連線恢復到剛建立時的狀態

查詢快取

建立連線後就可以執行這條 select 語句了,此時就到了 查詢快取這一步。MySQL 執行某個查詢語句時,會先到查詢快取中看看,之前是否執行過。之前執行過的語句和對應的結果以 key-value 的形式被直接快取在記憶體中。其中 key 就是查詢的語句,value 就是查詢的結果。如果能在查詢語句在快取中命中,就不需要在執行語句查表,可以直接返回結果,從而提高執行效率如果查詢快取中沒有,就會執行 select 語句查表,執行完成後的結果會被存入查詢快取中。但是查詢快取 弊大於利
。因為查詢快取很容易失效,只要對錶進行更新,表上所有的查詢快取都會清空,對於更新頻繁的表,查詢快取的命中率很低。MySQL 中的 query_cache_type 引數就是用來控制查詢快取的,將這個引數設定為 DEMAND 後,預設的 SQL 語句都不使用查詢快取。對於確定要使用查詢快取的語句,可以在語句裡新增 SQL_CACHE 顯示指定:
selectSQL_CACHE*fromTwhere ID = 10;
而在 MySQL8.0 版本中,已經沒有這個功能了 分析器如果沒有命中查詢快取,就得執行語句。首先 MySQL 會對 SQL 語句進行解析,類似於編譯原理中的分析。分析器先會做 “詞法分析”。因為輸入的內容是字串和空格組成的語句,MySQL 需要識別字符串的內容以及代表的含義。從輸入的 “selelct”得到該語句是一條查詢語句,把字串“T”識別成某個表的名字,把“ID” 識別成表中欄位的名稱。做完 “詞法分析” 之後,就是 “語法分析” 的部分。語法分析器會根據語法規則判斷輸入的 SQL 語句是否正確,比如是否出現單詞錯誤等 優化器經過分析器的分析,MySQL 已經直到要完成什麼任務,但是在具體執行之前,還要經過優化器的處理。優化器是在表中有多個索引的時候,決定使用哪個索引;或是某個語句多表查詢,決定每個表的連線順序。不同的連線順序,執行起來的效率可能會有所不同,優化器的作用就是決定選擇使用哪一個方案。優化器階段選擇完成後,某個語句的執行方案就確定了,進入執行階段 執行器開始執行前,要先判斷輸入這條語句的使用者對要查詢的表有沒有許可權,若沒有就返回沒有許可權的錯誤資訊。而如果命中查詢快取,在返回結果的時候,也會做許可權驗證。驗證許可權的部分在優化器之前完成。執行開頭的 select 語句時,表 T 中 ID 欄位沒有索引,那麼執行的流程就是下面這樣的:
  1. 呼叫 InnoDB引擎介面,取表 T 的第一行,判斷 ID 的值是否為 10,如果不是就跳過,如果是就將這一行存在結果集中

  2. 呼叫介面取下一行,重複判斷 ID 的值,直到取到表的最後一行。也就是說對錶 T 進行全表掃描,取出 ID = 10 的行並將其儲存到結果集中

  3. 執行器將上述遍歷過程中所有滿足條件的行組成的記錄集作為結果集返回給客戶端

可以在資料庫的慢查詢日誌中看到 rows_examined 的欄位,表示這個語句執行過程中掃描了多少行,這個值就是在執行器每次呼叫引擎取資料行時累加的

總結
  1. MySQL 分為 Server 層和儲存引擎層。Server 層中包含聯結器、查詢快取、分析器、優化器、執行器。儲存引擎層預設使用 InnoDB

  2. 聯結器用於和客戶端建立連線,驗證許可權;連線分為長連線和短連線

  3. 查詢快取的儲存形式為 key-value,key 是查詢語句,value 是查詢結果。查詢快取容易失效,更新頻繁的表命中率很低

  4. 分析器的任務是詞法分析和語法分析。詞法分析識別輸入的語句要完成的任務,語法分析分析輸入的語句是否正確。輸入語句時出現錯誤,就是分析器發現的

  5. 優化器選擇執行效率最高的方案,然後交給執行器執行

  6. 根據查詢的欄位是否有索引,執行器決定是否全表掃描。將符合條件的記錄集作為結果集返回客戶端。不管是否命中查詢快取,返回結果前都要做許可權驗證