MySQL簡介
MySQL是一個關系型數據庫管理系統,由瑞典MySQL AB 公司開發,屬于 Oracle 旗下產品。由于其體積小、速度快、總體擁有成本低,尤其是開放源碼這一特點,一般中小型網站的開發都選擇 MySQL 作為數據庫。
近年來,隨著MySQL的不斷發展,越來越多的互聯網公司也選擇了MySQ作為數據庫存儲,其中不乏一些大廠,說明MySQL越來越受開發者的青睞。
MySQL體系結構
- Connectors組件提供對外的連接,供JDBC、ODBC、php、 Python等進行數據庫連接
- 連接池組件(Connection Pool) 負責接收外部請求,將請求轉發到對應的模塊,每個連接成功的請求都會分配一個線程來負責維護客戶端與MySQL服務器的連接,該線程負責接收客戶端的請求,返回結果給客戶端
- 管理服務和工具組件(Management Service & Utilities)負責MySQL服務端的管理,如備份、恢復、安全、配置等
- SQL接口組件(SQL Interface) 負責處理DML、DDL、存儲過程、觸發器等SQL操作,并返回結果
- 查詢分析器組件(Parser) 分析SQL(檢查語法、合法性)
- 優化器組件(Optimizer) 優化SQL命令進行標準的優化分析
- 緩沖組件(Caches & Buffers) 用于查詢數據的緩沖和緩存
- 插件式存儲引擎(Pluggable Storage Engines) MySQL特有的特性,提供了各種類型的存儲引擎用于不同的業務場景
- 物理文件(File System) 存儲MySQL 數據庫文件、日志文件、redo日志、Undo日志、索引等文件
MySQL區別于其他數據庫最重要的一個特點就是插件式存儲引擎
存儲引擎是底層物理結構的實現,每個存儲引擎開發者可以按照自己的意愿來進行開發
存儲引擎是基于表的,而不是數據庫。也就是同一個庫中的不同表可以采用不同的存儲引擎
存儲引擎的好處是,每個存儲引擎都有各自的特點,能夠根據具體的應用建立不同存儲引擎表
MySQL存儲引擎
由于MySQL數據庫開源特性,產生了很多種不同的存儲引擎,下面來介紹幾種常用的存儲引擎
InnoDB存儲引擎
InnoDB存儲引擎支持事務,其設計目標主要面向在線事務處理(OLTP)的應用
其特點是行鎖設計、支持外鍵,并支持類似于Oracle的非鎖定讀,即默認讀取操作不會產生鎖
從MySQL數據庫5.5.8版本開始,InnoDB存儲引擎是默認的存儲引擎
InnoDB通過使用多版本并發控制(MVCC)來獲得高并發性,并且實現了SQL標準的4種隔離級別,默認為REPEATABLE級別。同時,使
用一種被稱為next-key locking的策略來避免幻讀(phantom)現象的產生。除此之外,InnoDB儲存引擎還提供了插入緩沖(insert
buffer)、二次寫(double write)、自適應哈希索引(adaptive hash index)、預讀(read ahead)等高性能和高可用的功能
實際工作中,InnoDB應該是用的最多的存儲引擎
MyISAM存儲引擎
MyISAM存儲引擎不支持事務、表鎖設計,支持全文索引,主要面向一些OLAP數據庫應用
在MySQL 5.5.8版本之前MyISAM存儲引擎是默認的存儲引擎(除windows版本外),5.5.8以后默認存儲引擎就換成InnoDB
MyISAM存儲引擎表由MYD和MYI組成,MYD用來存放數據文件,MYI用來存放索引文件
注意 對于MyISAM存儲引擎表,MySQL數據庫只緩存其索引文件,數據文件的緩存交由操作系統本身來完成,這與其他使用LRU算法緩存
數據的大部分數據庫大不相同。此外,在MySQL 5.1.23版本之前,無論是在32位還是64位操作系統環境下,緩存索引的緩沖區最大只能設置為4GB。在之后的版本中,64位系統可以支持大于4GB的索引緩沖區
NDB存儲引擎
NDB存儲引擎是一個集群存儲引擎,類似于Oracle的RAC集群,不過與Oracle RAC share everything架構不同的是,其結構是
sharenothing的集群架構,因此能提供更高的可用性
NDB的特點是數據全部放在內存中(從MySQL 5.1版本開始,可以將非索引數據放在磁盤上),因此主鍵查找(primary key lookups)的
速度極快,并且通過添加NDB數據存儲節點(Data Node)可以線性地提高數據庫性能,是高可用、高性能的集群系統
關于NDB存儲引擎,有一個問題值得注意,那就是NDB存儲引擎的連接操作(JOIN)是在MySQL數據庫層完成的,而不是在存儲引擎層完成的。這意味著,復雜的連接操作需要巨大的網絡開銷,因此查詢速度很慢
Memory存儲引擎
Memory存儲引擎(之前稱HEAP存儲引擎)將表中的數據存放在內存中,如果數據庫重啟或發生崩潰,表中的數據都將消失。它非常適合
用于存儲臨時數據的臨時表,以及數據倉庫中的緯度表。Memory存儲引擎默認使用哈希索引,而不是我們熟悉的B+樹索引
雖然Memory存儲引擎速度非常快,但在使用上還是有一定的限制。比如,只支持表鎖,并發性能較差,并且不支持TEXT和BLOB列類型。
最重要的是,存儲變長字段(varchar)時是按照定常字段(char)的方式進行的,因此會浪費內存
Archive存儲引擎
Archive存儲引擎只支持INSERT和SELECT操作,從MySQL 5.1開始支持索引。Archive存儲引擎使用zlib算法將數據行(row)進行壓縮后存儲,壓縮比一般可達1∶10。正如其名字所示,Archive存儲引擎非常適合存儲歸檔數據,如日志信息。Archive存儲引擎使用行鎖來實現高并發的插入操作,但是其本身并不是事務安全的存儲引擎,其設計目標主要是提供高速的插入和壓縮功能。
Federated存儲引擎
Federated存儲引擎表并不存放數據,它只是指向一臺遠程MySQL數據庫服務器上的表。這非常類似于SQL Server的鏈接服務器和Oracle
的透明網關,不同的是,當前Federated存儲引擎只支持MySQL數據庫表,不支持異構數據庫表。
Maria存儲引擎
Maria存儲引擎是新開發的引擎,設計目標主要是用來取代原有的MyISAM存儲引擎,從而成為MySQL的默認存儲引擎。
Maria存儲引擎的特點是:支持緩存數據和索引文件,應用了行鎖設計,提供了MVCC功能,支持事務和非事務安全的選項,以及更好的BLOB字符類型的處理性能。
SQL是如何執行的
一條查詢的SQL發送到MySQL服務器被執行,返回查詢結果,這中間經歷了什么?下面我們來看一下一條SQL語句從客戶端發送給MySQL服務器,MySQL到底執行了哪些操作?
如上圖所示
- 客戶端SQL發送到MySQL服務端,首先會去查詢緩存里面查找,如果多次執行同一個SQL是會命中緩存中,此時直接通過緩存來取數據
- 若沒有命中查詢緩存,則將SQL發送給解析器,解析器會對SQL過行語法、語義分析,同時也會對SQL合法性進行校驗
- SQL語義解析出來后,優化器會對SQL語義進行優化,比如,是走索引還是全表掃描,優化器會根據實際情況來確定一個最優的執行方案(當然,不一定是最優的,只是給出MySQL認為是最優的執行方案)
- 優化完畢后,就給到執行器進行執行SQL,取出SQL執行結果
- 最后將執行結果返回給客戶端
簡單歸納一下,一條SQL在MySQL中的執行過程如下:SQL ==> 查詢緩存 ==> 解析器 ==> 優化器 ==> 執行器
當然,實際的過程遠遠比這個要復雜,這里只是列出來大致的步驟和過程,方便大家理解