# 虎年行大運 ~ MySQL - MyISAM V.S. InnoDB ## 【前言】 不少在使用 MySQL 的朋友應該都有遇到過要使用不同 Engine 的時候,究竟~ 在 **MyISAM** 和 **InnoDB** 有何差異? 為何要在某些情境選用 **InnoDB**? 又為何 MySQL 的預設是 **MyISAM** 呢? 文章下面帶你了解兩者優缺~ 讓你更清楚兩者差異,面對業務邏輯可以更輕鬆做判斷! ## 【MyISAM】 首先介紹 **MyISAM**,是 MySQL 最早的 Engine,也是建置資料庫時的預設選項。 是基於傳統 ISAM 型別的設定,ISAM 是 Indexed Sequential Access Method 的簡寫,意即為 **循索引的順序訪問資料的方法** 其特點就是以**查詢效能**和**大容量儲存空間**為主打,其查找的速度非常快,這是因為 MyISAM 只管理索引資料,且當索引資料大於系統分配資源時,會自動 cache 在記憶體,從而騰出空間載入更多索引,這讓 MyISAM 在處理查詢動作的表現上優於 InnoDB,因為 InnoDB 是資料和索引一併存放,並將資料做 cache,反過來說,當記憶體空間越大則 InnoDB 的表現越強,但在高併發的查詢需求情況下 MyISAM 的處理速度還是樂勝。 支援 **2^32^** 筆資料,以免費軟體來說算是相當優異的表現,如果有加入 **--with-big-tables** 指令的話,則可以再多儲存一倍的空間 (**2^32^ * 2**) **不支援事務處理(Transaction)**,亦**不支援外來鍵(FK)**,且在處理 Select, Insert, Update, Delete 的時候,會鎖住資料表,僅能在尾端部分進行 Insert 的動作,因此在高併發的 Update/Delete 需求情況下,其表現不如 InnoDB 快,且若資料表有毀損,則修復的時間也比 InnoDB 更長。 在 Auto_Increment 的部分比 InnoDB 快,因為當序列的值被刪除後,將不再使用其順序上的空位,而是單純的往後增加。且可以與其他欄位一起做為複數 Index 使用。 在儲存的部分會分成三個檔案存放,分別為 **.frm** (Table Format), **.MYD** (Data File), **.MYI** (Index File),提高了查詢上的彈性,增快其作業速度。 ## 【InnoDB】 InnoDB 是 MySQL 不同於 MyISAM 的另一種類型,如果說 MyISAM 強調的是查詢速度和大容量,那 InnoDB 則是走向精緻且具備進階業務處理能力的方向。 **支援事務處理 Transaction**,包含 RollBack(回溯), Crash Recovery capabilities(修復), Transaction Safe(安全) 等基本該有的特性。這也是 InnoDB 與 MyISAM 最大的不同,也是最重要的一點。 **支援外來鍵(FK)**,支援關聯式資料庫設計。 **不支援 FullText 類型的索引** (MyISAM 支援)。 不同於 MyISAM 的鎖是 **Table-level Lock**,InnoDB 是 **Row-level Lock**,因此在處理 Insert, Update, Delete 的速度比 MyISAM 快很多。Kai 不會說穩定度,是因為事務處理會遇到的問題 InnoDB 都會遇到,因此還是取決於設計師針對業務處理上的調整而定。 > 在清空資料表這件事情上,InnoDB 卻遠不如 MyISAM 高效,原因是 MyISAM 會直接清空表內容,但 InnoDB 卻會一筆一筆執行並 Commit 後才接下一筆。 > 這算是個有趣的差異~ ## 【差異列表】 上面長長一堆,直接幫大家整理在下面表格內 | 項目 | MyISAM | InnoDB | | ---- | ---- | ---- | | MySQL 中的設計 | 預設選項 | 手動設定 | | 著重部分 | 查詢效能優先 | 事務處理優先 | | 儲存實體 | 每個表的檔案都分為三個檔案: **.frm** (Table Format), **.MYD** (Data File), **.MYI** (Index File)|資料與索引皆在同一份檔案中,檔案又可因 **innodb_file_per_table** 參數調整成所有資料表存於一份檔案或是分成各表的檔案儲存| | 佔用空間 | 較小 | 較大 | | 備份 (無Slave狀況) | 因長時間讀取表造成的 Table-level Lock 有很高的 Inconsistent Backup 風險 | 透過事務做 Consistent Backup 避免 Inconsistent 狀況 | | 鎖級別 | Table-level Lock | Row-level Lock | | 支援外來鍵 (FK) | 不支援 | 支援 | | 支援事務處理 | 不支援 | 支援 | | 支援 FullText 全文索引 | 支援 | 不支援 (可用 **sphinx** 外掛套件取得支援) | | Auto_Increment | 刪除不填補;可與其他欄位做複數索引 | 若存在該類型欄位,則必須為其建立一個索引;不可與其他欄位做複數索引;優先填補空位值 | | 資料表的主鍵或索引 | 允許無主鍵、無索引資料表 | 若都無,會自動建立隱藏主鍵 | | COUNT() 函式 | 有保存資料表總行數,但若有查詢條件,還是會做全表檢索 | 沒有保存總行數,一訂做全表檢索 | 首頁 [Kai 個人技術 Hackmd](/2G-RoB0QTrKzkftH2uLueA) ###### tags: `MySQL`