MySQL是我們經常使用的資料庫處理系統(DBMS),不知小夥伴們有沒有注意過其中的“存儲引擎”(storage_engine)呢?有時候面試題中也會問道MySQL幾種常用的存儲引擎的差別。這次就簡短侃一下存儲引擎那些事兒。
先去查一下“引擎”概念。
引擎(Engine)是電子平台上開發程式或系統的核心元件。利用引擎,開發者可迅速建立、鋪設程式所需的功能,或利用其輔助程式的運轉。一般而言,引擎是一個程式或一套系統的支援部分。常見的程式引擎有遊戲引擎,搜尋引擎,殺毒引擎等。
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中一類特殊的存儲引擎。它使用存儲在記憶體中的内容來建立表,而且資料全部放在記憶體中。這些特性與前面的兩個很不同。
每個基于MEMORY存儲引擎的表實際對應一個磁盤檔案。該檔案的檔案名與表名相同,類型為frm類型。該檔案中隻存儲表的結構。而其資料檔案,都是存儲在記憶體中,這樣有利于資料的快速處理,提高整個表的效率。值得注意的是,伺服器需要有足夠的記憶體來維持MEMORY存儲引擎的表的使用。如果不需要了,可以釋放記憶體,甚至删除不需要的表。
MEMORY預設使用哈希索引。速度比使用B型樹索引快。當然如果你想用B型樹索引,可以在建立索引時指定。
注意,MEMORY用到的很少,因為它是把資料存到記憶體中,如果記憶體出現異常就會影響資料。如果重新開機或者關機,所有資料都會消失。是以,基于MEMORY的表的生命周期很短,一般是一次性的。
四.怎樣選擇存儲引擎
在實際工作中,選擇一個合适的存儲引擎是一個比較複雜的問題。每種存儲引擎都有自己的優缺點,不能籠統地說誰比誰好。

InnoDB:支援事務處理,支援外鍵,支援崩潰修複能力和并發控制。如果需要對事務的完整性要求比較高(比如銀行),要求實作并發控制(比如售票),那選擇InnoDB有很大的優勢。如果需要頻繁的更新、删除操作的資料庫,也可以選擇InnoDB,因為支援事務的送出(commit)和復原(rollback)。
MyISAM:插入資料快,空間和記憶體使用比較低。如果表主要是用于插入新記錄和讀出記錄,那麼選擇MyISAM能實作處理高效率。如果應用的完整性、并發性要求比 較低,也可以使用。
MEMORY:所有的資料都在記憶體中,資料的處理速度快,但是安全性不高。如果需要很快的讀寫速度,對資料的安全性要求較低,可以選擇MEMOEY。它對表的大小有要求,不能建立太大的表。是以,這類資料庫隻使用在相對較小的資料庫表。
注意,同一個資料庫也可以使用多種存儲引擎的表。如果一個表要求比較高的事務處理,可以選擇InnoDB。這個資料庫中可以将查詢要求比較高的表選擇MyISAM存儲。如果該資料庫需要一個用于查詢的臨時表,可以選擇MEMORY存儲引擎。
原文釋出時間為:2018-08-27
本文作者:my筆觸
本文來自雲栖社群合作夥伴“
Java架構沉思錄”,了解相關資訊可以關注“
”。