如果想看自己的資料庫預設使用的那個儲存引擎,可以透過使用指令:
SHOW VARIABLES LIKE 'storage_engine';
#一、InnoDB儲存引擎
1. InnoDB是事務型資料庫的首選引擎
支援事務安全表(ACID)
交易的ACID屬性:即原子性、一致性、隔離性、持久性
a.原子性:原子性也就是說這組語句要麼全部執行,要麼全部不執行,如果交易執行到一半出現錯誤,資料庫就要回滾到交易開始執行的地方。
實作:主要是基於MySQ日誌系統的redo和undo機制。事務是一組SQL語句,裡面有選擇,查詢、刪除等功能。每條語句執行會有一個節點。例如,刪除語句執行後,在事務中有個記錄保存下來,這個記錄中儲存了我們什麼時候做了什麼事。如果出錯了,就會回滾到原來的位置,redo裡面已經儲存了我做過什麼事了,然後逆向執行一遍就可以了。
b.一致性:交易開始前和結束後,資料庫的完整性限制並沒有被破壞。 (eg:例如A向B轉賬,不可能A扣了錢,B卻沒有收到)
c.隔離性:同一時間,只允許一個事務請求同一數據,不同的事務之間彼此沒有任何干擾;
如果不考慮隔離性則會出現幾個問題:
i、髒讀:是指在一個事務處理過程裡讀取了另一個未提交的事務中的數據(當一個事務正在多次修改某個數據,而在這個事務中這多次的修改都還未提交,這時一個並發的事務來訪問該數據,就會造成兩個事務得到的數據不一致);(讀取了另一個事務未提交的髒數據)
ii、不可重複讀取:在對於資料庫中的某個數據,一個事務範圍內多次查詢卻返回了不同的數據值,這是由於在查詢間隔,被另一個事務修改並提交了;(讀取了前一個事務提交的數據,查詢的都是同一個資料項)
iii、虛讀(幻讀):是交易非獨立執行時發生的一種現象(eg:事務T1對一個表中所有的行的某個資料項做了從「1」修改為「2」的操作,這時事務T2又對這個表中插入了一行資料項,而這個資料項的數值還是為「1」並且提交給資料庫。而操作事務T1的使用者如果再查看剛剛修改的數據,會發現還有一行沒有修改,其實這行是從事務T2中添加的,就好像產生幻覺一樣);(讀取了前一個事務提交的數據,針對一批資料整體)
d.持久性:交易完成後,交易對資料庫的所有更新將被儲存到資料庫,不能回滾
#2.InnoDB是mySQL預設的儲存引擎
預設的隔離等級是RR,並且在RR的隔離等級下更近一步,透過多版本並發控制( MVCC)解決不可重複讀取問題,加上間隙鎖定(也就是並發控制)解決幻讀問題。因此InnoDB的RR隔離等級其實實現了串列化等級的效果,而保留了比較好的並發效能。
MySQL資料庫提供給我們的四個隔離等級:
a、Serializable
(串列化):可避免髒讀、無法重複讀取、幻讀的發生;
b、Repeatable read
(可重複讀取):可避免髒讀、無法重複讀取的發生;
c、Read committed
(讀取已提交):可避免髒讀的發生;
d、Read uncommitted
(讀取未提交):最低級別,任何情況都無法保證;
從a----d隔離等級由高到低,等級越高,執行效率越低
3.InnoDB支援行級鎖定。
行級鎖定可以最大程度的支援並發,行級鎖定是由儲存引擎層實現的。
鎖定:鎖定的主要功能是管理共享資源的並發訪問,用於實現事務的隔離性
類型:共享鎖定(讀鎖定)、獨佔鎖定(寫入鎖定)
MySQL鎖定的力道:表級鎖定(開銷小、並發性低),通常在伺服器層實現
行級鎖定(開銷大、並發性高),只會在儲存引擎層面進行實作
4、InnoDB是為處理巨大資料量的最大效能設計。
它的CPU效率可能是任何基於磁碟的關係型資料庫引擎所不能匹敵的
5、InnoDB儲存引擎完全與MySQL伺服器整合
InnoDB儲存引擎為在主記憶體中快取資料和索引而維持它自己的緩衝池。 InnoDB將它的表和索引在一個邏輯表空間中,表空間可以包含幾個檔案(或原始磁碟檔案);
6、InnoDB支援外鍵完整性約束
#儲存表中的資料時,每張表的儲存都會依照主鍵順序存放,如果沒有顯示在表定義時指定主鍵。 InnoDB會為每一行產生一個6位元組的ROWID,並以此作為主鍵
#7、InnoDB被用在眾多需要高效能的大型資料庫網站上
8、InnoDB中不保存表格的行數(eg:select count(*)from table時,InnoDB需要掃描一遍整個表來計算有多少行);清空整個表時,InnoDB是一行一行的刪除,效率非常慢;
InnoDB不建立目錄,使用InnoDB時,MySQL將在MySQL資料目錄下建立一個名為ibdata1的10MB大小的自動擴充資料文件,以及兩個名為ib_logfile0和ib_logfile1的5MB大小的日誌檔案
二、InnoDB引擎的底層實作
InnoDB的儲存檔案有兩個,後綴名稱分別是.frm和.idb ;其中.frm是表的定義文件, .idb是表的資料檔。
1、InnoDB引擎採用B Tree結構來作為索引結構
B-Tree(平衡多路查找樹):為磁碟等外部儲存裝置設計的一種平衡查找樹
系統從磁碟讀取資料到記憶體時是以磁碟區塊位基本單位的,位於同一磁碟區塊中的資料會被一次讀取出來,而不是按需讀取。
InnoDB儲存引擎使用頁作為資料讀取單位,頁是其磁碟管理的最小單位,預設page大小是16k.
系統的一個磁碟區塊的儲存空間往往沒有那麼大,因此InnoDB每次申請磁碟空間時都會是若干位址連續磁碟區塊來達到頁的大小16KB。
InnoDB在把磁碟資料讀入磁碟時會以頁為基本單位,在查詢資料時,如果一個頁中的每個資料都能助於定位資料記錄的位置,這將會減少磁碟I/O的次數,提高查詢效率。
B-Tree結構的資料可以讓系統有效率的找到資料所在的磁碟區塊
B-Tree中的每個節點根據實際情況可以包含大量的關鍵字資訊和分支,範例
每個節點佔用一個磁碟區的磁碟空間,一個節點上有兩個升序排序的關鍵字和三個指向子樹根節點的指針,指針儲存的是子節點所在磁碟區塊的位址。
以根節點為例,關鍵字為17和35,P1指標指向的子樹的資料範圍小於17,P2指標指向的子樹的資料範圍為17----35,P3指針指向的子樹的資料範圍大於35;
模擬查找關鍵字29的過程:
a.根據根節點找到磁碟區塊1,讀入記憶體。 【磁碟I/O操作第一次】
b.比較關鍵字29在區間(17,35),找到磁碟區塊1的指標P2;
c.根據P2指標找到磁碟區塊3,讀入記憶體。 【磁碟I/O操作第二次】
d.比較關鍵字29在區間(26,30),找到磁碟區塊3的指標P2;
e.根據P2指標找到磁碟區塊8,讀入記憶體。 【磁碟I/O操作第三次】
f.在磁碟區塊8中的關鍵字清單中找到關鍵字29.
MySQL的InnoDB儲存引擎在設計時是將根節點常駐記憶體的,因此力求達到樹的深度不超過3,也就是I/O不需要超過三次;
#分析上面的結果,發現需要三次磁碟I/O操作,和三次記憶體查找操作。由於記憶體中的關鍵字是一個有序表結構,可以利用二分法查找來提高效率;而三次磁碟I/O操作時影響整個B-Tree查找效率的決定因素。
B Tree
B Tree是在B-Tree基礎上的最佳化,使其更適合實作外儲存索引結構,B-Tree中每個節點中有key,也有data,而每一頁的儲存空間是有限的,如果data資料較大時將會導致每個節點(即一個頁)能儲存的key的數量很小。當儲存的資料量很大時同樣會導致B-Tree的深度較大,增大查詢時的磁碟I/O次數,進而影響查詢效率。
在B Tree中所有資料記錄節點都是按照鍵值大小順序存放在同一層的葉子節點上,而非葉子節點上只儲存key值信息,這樣可以大大加大每個節點存儲的key值數量,降低B Tree的高度;
通常在B Tree上有兩個頭指針,一個指向根節點,另一個指向關鍵字最小的葉子節點,而且所有葉子節點(即資料節點)之間都是一種鍊式環結構。
因此可以對B Tree進行兩種查找運算,一種是對於主鍵的範圍查找和分頁查找,另一種是從根節點開始,進行隨機查找。
InnoDB中的B Tree
InnoDB是以ID為索引的資料儲存
採用InnoDB引擎的資料儲存檔案有兩個,一個定義文件,一個是數據文件。
InnoDB透過B Tree結構對ID建立索引,然後在葉子節點中儲存記錄
若建立索引的欄位不是主鍵ID,則對該欄位建立索引,然後在葉子節點中儲存的是該記錄的主鍵,然後透過主鍵索引找到對應記錄。
相了解更多相關問題請上PHP中文網:PHP影片教學
#以上是超細緻的mysql儲存引擎-InnoDB的解說的詳細內容。更多資訊請關注PHP中文網其他相關文章!