深入理解MySQL底層實現


本文摘自:http://harlon.org/2018/06/20/database/

深入理解MySQL底層實現

這里選用MySQL作為了解數據庫的底層實現,這是因為MySQL是目前最常用的數據庫,了解它的底層實現也基本上對目前大數據的數據庫所用的技術會有一個大致的了解。數據庫最主要的索引設計,了解數據庫的索引設計基本上就對數據庫有了大致的了解,其次對其事務的ACID操作實現原理做以分析,以及數據庫中所用到的提高其性能的優化等等。


存儲引擎

MySQL常用的存儲引擎有InnoDB和MyISAM,其中MyISAM是MySQL的默認存儲引擎。

InnoDB

InnoDB的存儲文件有兩個,后綴名分別是.frm和.idb,其中.frm是表的定義文件,而idb是數據文件。InnoDB中存在表鎖和行鎖,不過行鎖是命中索引的情況下才會起作用的。
InnoDB支持事務,且支持四種隔離級別,即原子性(atomicity)、一致性(consistency)、隔離性(isolation)、持久性(durability)。

  • 原子性:一個事務(transaction)中的所有操作,要么全部完成,要么全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被恢復(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
  • 一致性:在事務開始之前和事務結束以后,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及后續數據庫可以自發性地完成預定的工作。
  • 隔離性:數據庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
  • 持久性:事務處理結束后,對數據的修改就是永久的,即便系統故障也不會丟失。

MyISAM

MyISAM的存儲文件有三個,后綴名分別是.frm、.MYD、.MYI,其中.frm是表文件,.MYD是數據文件,.MYI是索引文件。
MyISAM只支持表鎖,且不支持事務。MyISAM由於有單獨的索引文件,在讀取數據方面性能很高。


InnoDB和MyISAM的區別

MyISAM強調的是性能,每次查詢都具有原子性,其執行速度比InnoDB類型更快,但不提供事務支持。InnoDB:提供事務支持事務,外部鍵等高級數據庫功能。 具有事務(commit)、回滾(rollback)和崩潰修復能力(crash recovery capabilities)的事務安全(transaction-safe (ACID compliant))型表。
MyISAM只支持表鎖,用戶在操作其表時,select、update、delete、insert語句都會自動給表加鎖,如果加鎖以后的表滿足insert並發的情況下,可以在表的尾部插入新的數據。


選擇存儲引擎的基本原則

  • 采用MyISAM
    • R/W > 100:1 且update相對較少
    • 並發不高
    • 表數據量小
    • 硬件資源有限
  • 采用InooDB引擎
    • R/W比較少,頻繁更新大字段
    • 表數據量超過1000萬,並發高
    • 安全性和可用性要求高

索引存儲結構

InnoDB和MyISAM都是用B+Tree來存儲數據的。

磁盤的IO請求過程

磁盤可以從划分成柱面、磁道和扇區,每一個扇區是以512字節為單位的,磁盤要想確定一個數據的位置,首先傳入數據的虛擬地址,控制器將這個虛擬地址轉換為物理地址,每一個物理地址由<柱面號,磁道號,扇區號>唯一確定。
磁盤為了讀取扇區號上的數據:

  • 首先必須找到柱面,即磁頭需要移動對准相應磁道,這個過程叫做尋道,所耗費時間叫做尋道時間。
  • 然后目標扇區旋轉到磁頭下,即磁盤旋轉將目標扇區旋轉到磁頭下,這個過程耗費的時間叫做旋轉時間。
  • 之后讀取數據,拷貝到內存中,這個過程耗費的時間叫做數據傳輸時間。
    為了提高IO的效率,磁盤每次讀取數據的時候,並不是嚴格按照一個扇區返回,而是采用預讀策略,按照頁為單位的,一般是4k。

索引

建立索引的目的為了優化查找過程,有關這方面的數據結構可以參讀:數據結構之高級樹
B-Tree作為索引結構,如果存儲的數據量很大時會導致B-Tree的深度較大,增大查詢的磁盤IO次數,從而影響到查詢效率。
而在B+Tree中,所有數據記錄節點都是按照值大小放在一層的葉子節點上,而非葉子節點上只存儲key值信息,這樣可以大大加大每個節點存儲的key值數量,降低B+Tree的高度。
B+Tree相對B-Tree的基礎有兩大變化:

  • 數據是存在葉子節點上的
  • 數據節點之間是有指針指向的
    B+Tree

    聚集索引

    InnoDB 是以 ID 為索引的數據存儲。
    采用 InnoDB 引擎的數據存儲文件有兩個,一個定義文件,一個是數據文件。
    InnoDB 通過 B+Tree 結構對 ID 建索引,然后在葉子節點中存儲記錄。
    非聚類索引

    非聚集索引

    Myisam 引擎也是采用的 B+Tree 結構來作為索引結構。
    由於 Myisam 中的索引和數據分別存放在不同的文件,所以在索引樹中的葉子節點中存的數據是該索引對應的數據記錄的地址,由於數據與索引不在一起,所以 Myisam 是非聚簇索引。
    聚類索引

    索引覆蓋

    所謂的索引覆蓋就是索引包含查詢的所有數據,就稱為覆蓋索引。覆蓋索引是一種非常強大的工具,能大大提高查詢性能。只需要讀取索引而不用讀取數據,有以下一些優點:
  • 索引項通常比記錄要小,所以MySQL訪問更少的數據;
  • 索引都按值的大小順序存儲,相對於隨機訪問記錄,需要更少的I/O;
  • 大多數據引擎能更好的緩存索引。比如MyISAM只緩存索引。
  • 覆蓋索引對於InnoDB表尤其有用,因為InnoDB使用聚集索引組織數據,如果二級索引中包含查詢所需的數據,就不再需要在聚集索引中查找了。




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM