MySQL常見的三種存儲引擎


Ok,我們知道了,引擎就是一個程序的核心組件。

簡單來說,存儲引擎就是指表的類型以及表在計算機上的存儲方式

存儲引擎的概念是MySQL的特點,Oracle中沒有專門的存儲引擎的概念,Oracle有OLTP和OLAP模式的區分。不同的存儲引擎決定了MySQL數據庫中的表可以用不同的方式來存儲。我們可以根據數據的特點來選擇不同的存儲引擎

在MySQL中的存儲引擎有很多種,可以通過“SHOW ENGINES”語句來查看。下面重點關注InnoDB、MyISAM、MEMORY這三種。

一、InnoDB存儲引擎

InnoDB給MySQL的表提供了事務處理、回滾、崩潰修復能力和多版本並發控制的事務安全。在MySQL從3.23.34a開始包含InnnoDB。它是MySQL上第一個提供外鍵約束的表引擎。而且InnoDB對事務處理的能力,也是其他存儲引擎不能比擬的。靠后版本的MySQL的默認存儲引擎就是InnoDB。

InnoDB存儲引擎總支持AUTO_INCREMENT。自動增長列的值不能為空,並且值必須唯一。MySQL中規定自增列必須為主鍵。在插入值的時候,如果自動增長列不輸入值,則插入的值為自動增長后的值;如果輸入的值為0或空(NULL),則插入的值也是自動增長后的值;如果插入某個確定的值,且該值在前面沒有出現過,就可以直接插入。

InnoDB還支持外鍵(FOREIGN KEY)。外鍵所在的表叫做子表,外鍵所依賴(REFERENCES)的表叫做父表。父表中被字表外鍵關聯的字段必須為主鍵。當刪除、更新父表中的某條信息時,子表也必須有相應的改變,這是數據庫的參照完整性規則

InnoDB中,創建的表的表結構存儲在.frm文件中(我覺得是frame的縮寫吧)。數據和索引存儲在innodb_data_home_dir和innodb_data_file_path定義的表空間中。

InnoDB的優勢在於提供了良好的事務處理、崩潰修復能力和並發控制。缺點是讀寫效率較差,占用的數據空間相對較大

二、MyISAM存儲引擎

MyISAM是MySQL中常見的存儲引擎,曾經是MySQL的默認存儲引擎。MyISAM是基於ISAM引擎發展起來的,增加了許多有用的擴展。

MyISAM的表存儲成3個文件。文件的名字與表名相同。拓展名為frm、MYD、MYI。其實,frm文件存儲表的結構;MYD文件存儲數據,是MYData的縮寫;MYI文件存儲索引,是MYIndex的縮寫。

基於MyISAM存儲引擎的表支持3種不同的存儲格式。包括靜態型、動態型和壓縮型。其中,靜態型是MyISAM的默認存儲格式,它的字段是固定長度的;動態型包含變長字段,記錄的長度不是固定的;壓縮型需要用到myisampack工具,占用的磁盤空間較小。

MyISAM的優勢在於占用空間小,處理速度快。缺點是不支持事務的完整性和並發性

三、MEMORY存儲引擎

Memory存儲引擎是MySQL中的一類特殊的存儲引擎。其使用存儲在內存中的內容來創建表,而且所有數據也放在內存中。這些特性都與InnoDB,MyISAM存儲引擎不同。

OK,這里我們講解一些memory存儲引擎的文件存儲形式,索引類型,存儲周期和優缺點。

每個基於memory存儲引擎的表實際對應一個磁盤文件,該文件的文件名與表名相同,類型為frm類型。該文件只存儲表的結構,而其數據文件,都是存儲在內存中的,這樣有利於對數據的快速的處理,提高整個表的處理效率。

值得注意的是:服務器需要有足夠的內存來維持memory存儲引擎的表的使用。如果不需要了,可以釋放這些內存,甚至可以刪除不需要的表。

Memory存儲引擎默認使用哈希(HASH)索引,其速度比使用B型樹(BTREE)索引快。如果我們需要使用B型樹索引,可以在創建索引時選擇使用。

這里來整理一個小的技巧:

Memory存儲引擎通常很少用到,至少我是沒有用到過。因為Memory表的所有數據都是存儲在內存上的,如果內存出現異常會影響到數據的完整性。

如果重啟機器或者關機,表中的所有數據都將消失,因此,基於Memory存儲引擎的表的生命周期都比較短,一般都是一次性的。

Memory表的大小是受到限制的,表的大小主要取決於2個參數,分別是max_rows和max_heap_table_size。其中,max_rows可以在創建表時指定,max_heap_table_size的大小默認為16MB,可以按需要進行擴大。

因此,其基於內存中的特性,這類表的處理速度會非常快,但是,其數據易丟失,生命周期短。基於其這個缺陷,選擇Memory存儲引擎時需要特別小心。

四、怎樣選擇存儲引擎

在實際工作中,選擇一個合適的存儲引擎是一個比較復雜的問題。每種存儲引擎都有自己的優缺點,不能籠統地說誰比誰好

InnoDB:支持事務處理,支持外鍵,支持崩潰修復能力和並發控制。如果需要對事務的完整性要求比較高(比如銀行),要求實現並發控制(比如售票),那選擇InnoDB有很大的優勢。如果需要頻繁的更新、刪除操作的數據庫,也可以選擇InnoDB,因為支持事務的提交(commit)和回滾(rollback),還有需要主鍵自增或者外鍵的需求也需要InnoDB。

MyISAM:插入數據快,空間和內存使用比較低。如果表主要是用於插入新記錄和讀出記錄,那么選擇MyISAM能實現處理高效率。如果應用的完整性、並發性要求比 較低,也可以使用。

MEMORY:所有的數據都在內存中,數據的處理速度快,但是安全性不高。如果需要很快的讀寫速度,對數據的安全性要求較低,可以選擇MEMOEY。它對表的大小有要求,不能建立太大的表。所以,這類數據庫只使用在相對較小的數據庫表。

注意,同一個數據庫也可以使用多種存儲引擎的表。如果一個表要求比較高的事務處理,可以選擇InnoDB。這個數據庫中可以將查詢要求比較高的表選擇MyISAM存儲。如果該數據庫需要一個用於查詢的臨時表,可以選擇MEMORY存儲引擎。

五、InnoDB 索引到底是b+樹還是b樹

先從數據結構的角度來答。

題主應該知道B-樹和B+樹最重要的一個區別就是B+樹只有葉節點存放數據,其余節點用來索引,而B-樹是每個索引節點都會有Data域。

這就決定了B+樹更適合用來存儲外部數據,也就是所謂的磁盤數據

從Mysql(Inoodb)的角度來看,B+樹是用來充當索引的,一般來說索引非常大,尤其是關系性數據庫這種數據量大的索引能達到億級別,所以為了減少內存的占用,索引也會被存儲在磁盤上。

那么Mysql如何衡量查詢效率呢?磁盤IO次數,B-樹(B類樹)的特定就是每層節點數目非常多,層數很少,目的就是為了就少磁盤IO次數,當查詢數據的時候,最好的情況就是很快找到目標索引,然后讀取數據,使用B+樹就能很好的完成這個目的,但是B-樹的每個節點都有data域(指針),這無疑增大了節點大小,說白了增加了磁盤IO次數(磁盤IO一次讀出的數據量大小是固定的,單個數據變大,每次讀出的就少,IO次數增多,一次IO多耗時啊!),而B+樹除了葉子節點其它節點並不存儲數據,節點小,磁盤IO次數就少。這是優點之一。

另一個優點是什么,B+樹所有的Data域在葉子節點,一般來說都會進行一個優化,就是將所有的葉子節點用指針串起來。這樣遍歷葉子節點就能獲得全部數據,這樣就能進行區間訪問啦。

至於MongoDB為什么使用B-樹而不是B+樹,可以從它的設計角度來考慮,它並不是傳統的關系性數據庫,而是以Json格式作為存儲的nosql,目的就是高性能,高可用,易擴展。首先它擺脫了關系模型,上面所述的優點2需求就沒那么強烈了,其次Mysql由於使用B+樹,數據都在葉節點上,每次查詢都需要訪問到葉節點,而MongoDB使用B-樹,所有節點都有Data域,只要找到指定索引就可以進行訪問,無疑單次查詢平均快於Mysql(但側面來看Mysql至少平均查詢耗時差不多)。

總體來說,Mysql選用B+樹和MongoDB選用B-樹還是以自己的需求來選擇的。

六、Inoodb和MyISAM的區別

InnoDB的的二級索引的葉子節點存放的是KEY字段加主鍵值。因此,通過二級索引查詢首先查到是主鍵值,然后InnoDB再根據查到的主鍵值通過主鍵索引找到相應的數據塊。

MyISAM的二級索引葉子節點存放的還是列值與行號的組合,葉子節點中保存的是數據的物理地址。所以可以看出MYISAM的主鍵索引和二級索引沒有任何區別,主鍵索引僅僅只是一個叫做PRIMARY的唯一、非空的索引,且MYISAM引擎中可以不設主鍵。

InnoDB輔助索引的葉子結點保存的是主鍵(關聯主鍵索引);MyISAM則輔助和主鍵索引葉子節點均保存文件內容地址。這就是MyISAM和InnoDB最大的不同;

既然MyISAM和InnoDB是MySQL的兩代引擎,肯定會有一個提升,而InnoDB是最新一代,那么它到底優在哪里?

試想,MyISAM和InnoDB都是以B+樹為基礎實現的,相對於B樹的不同其實前面已經講過,即數據域和結點分離;

MyISAM更是索引和文件分離,B+樹的葉子結點的數據域存放的是文件內容的地址,主索引和輔助索引的B+樹都是如此,那么如果我改變了一個地址,是不是所有的索引樹都得改變,正如前面我們講的在磁盤上頻繁的讀寫操作是效率很低的,而這塊又不適用局部原理,因為邏輯上相鄰的結點,物理上不一定相鄰,那么這樣就會造成效率上的降低;

於是乎,InnoDB就產生了,它讓除了主索引以外的輔助索引的葉子結點的數據域都保存主鍵,先通過輔助索引找到主鍵,然后通過主鍵找到葉子結點的所有數據,聽起來貌似很麻煩,遍歷了兩棵樹,但是,這樣如果有了修改的話,改變的只是主索引,其它輔助索引都不用動,而且,數據庫中的樹的每一個結點的key可不是咱們給的那么少,試想如果一個結點有1024個key,那么高度為2的B+樹都有1024*1024個key,所以一般樹的高度都很低,所以,遍歷樹的消耗幾乎忽略不計


免責聲明!

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



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