MySQL
數據庫區別於其他數據庫的很重要的一個特點就是其插件式的表存儲引擎,其基於表,而不是數據庫。由於每個存儲引擎都有其特點,因此我們可以針對每一張表來挑選最合適的存儲引擎。
作爲DBA
,我們應該深刻的認識存儲引擎。今天介紹兩種最常見的存儲引擎和它們的區別:InnoDB
和MyISAM
。
InnoDB
存儲引擎
InnoDB
存儲引擎支持事務,其設計目標主要就是面向OLTP(On Line Transaction Processing 在線事務處理)
的應用。特點爲行鎖設計、支持外鍵,並支持非鎖定讀。從5.5.8
版本開始,InnoDB
成爲了MySQL
的默認存儲引擎。
InnoDB
存儲引擎採用聚集索引(clustered)的方式來存儲數據,因此每個表都是按照主鍵的順序進行存放,如果沒有指定主鍵,InnoDB
會爲每行自動生成一個6
字節的ROWID
作爲主鍵。
MyISAM
存儲引擎
MyISAM
存儲引擎不支持事務、表鎖設計,支持全文索引,主要面向OLAP(On Line Analytical Processing 聯機分析處理)
應用,適用於數據倉庫等查詢頻繁的場景。在5.5.8
版本之前,MyISAM
是MySQL
的默認存儲引擎。該引擎代表着對海量數據進行查詢和分析的需求。它強調性能,因此在查詢的執行速度比InnoDB
更快。
MyISAM
存儲引擎還有一個特點是隻緩存索引文件,而不緩存數據文件,這點非常獨特。
InnoDB
和MyISAM
的區別
事務
爲了數據庫操作的原子性,我們需要事務。保證一組操作要麼都成功,要麼都失敗,比如轉賬的功能。我們通常將多條SQL
語句放在begin
和commit
之間,組成一個事務。
InnoDB
支持,MyISAM
不支持。
主鍵
由於InnoDB
的聚集索引,其如果沒有指定主鍵,就會自動生成主鍵。MyISAM
支持沒有主鍵的表存在。
外鍵
爲了解決複雜邏輯的依賴,我們需要外鍵。比如高考成績的錄入,必須歸屬於某位同學,我們就需要高考成績數據庫裏有准考證號的外鍵。
InnoDB
支持,MyISAM
不支持。
索引
爲了優化查詢的速度,進行排序和匹配查找,我們需要索引。比如所有人的姓名從a-z
首字母進行順序存儲,當我們查找zhangsan
或者第44
位的時候就可以很快的定位到我們想要的位置進行查找。
InnoDB
是聚集索引,數據和主鍵的聚集索引綁定在一起,通過主鍵索引效率很高。如果通過其他列的輔助索引來進行查找,需要先查找到聚集索引,再查詢到所有數據,需要兩次查詢。
MyISAM
是非聚集索引,數據文件是分離的,索引保存的是數據的指針。
從InnoDB 1.2.x
版本,MySQL5.6
版本後,兩者都支持全文索引。
auto_increment
對於自增數的字段,InnoDB
要求必須有隻有該字段的索引。但MyISAM
可以將該字段與其他字段組成聯合索引。
錶行數
很常見的需求是看錶中有多少條數據,此時我們需要select count(*) from table_name
。
InnoDB
不保存錶行數,需要進行全表掃描。MyISAM
用一個變量保存,直接讀取該值,更快。當時當帶有where
查詢的時候,兩者一樣。
存儲
數據庫的文件都是需要在磁盤中進行存儲,當應用需要時再讀取到內存中。一般包含數據文件、索引文件。
InnoDB
分爲:
-
.frm
表結構文件 -
.ibdata1
共享表空間 -
.ibd
表獨佔空間 -
.redo
日誌文件
MyISAM
分爲三個文件:
-
.frm
存儲表定義 -
.MYD
存儲表數據 -
.MYI
存儲表索引
執行速度
如果你的操作是大量的查詢操作,如SELECT
,使用MyISAM
性能會更好。
如果大部分是刪除和更改的操作,使用InnoDB
。
delete
調用delete from table
時,MyISAM
會直接重建表,InnoDB
會一行一行的刪除,但是可以用truncate table
代替。參考: mysql清空表數據的兩種方式和區別。
鎖
MyISAM
僅支持表鎖,每次操作鎖定整張表。InnoDB
支持行鎖,每次操作鎖住最小數量的行數據。
表鎖相比於行鎖消耗的資源更少,且不會出現死鎖,但同時併發性能差。行鎖消耗更多的資源,速度較慢,且可能發生死鎖,但是因爲鎖定的粒度小、數據少,併發性能好。如果InnoDB
的一條語句無法確定要掃描的範圍,也會鎖定整張表。
當行鎖發生死鎖的時候,會計算每個事務影響的行數,然後回滾行數較少的事務。
數據恢復
MyISAM
崩潰後無法快速的安全恢復。InnoDB
有一套完善的恢復機制。
數據緩存
MyISAM
僅緩存索引數據,通過索引查詢數據。InnoDB
不僅緩存索引數據,同時緩存數據信息,將數據按頁讀取到緩存池,按LRU(Latest Rare Use 最近最少使用)
算法來進行更新。
如何選擇存儲引擎
創建表的語句都是相同的,只有最後的type
來指定存儲引擎。
MyISAM
- 大量查詢總
count
- 查詢頻繁,插入不頻繁
- 沒有事務操作
InnoDB
- 需要高可用性,或者需要事務
- 表更新頻繁
參考資料
- MySQL InnoDB索引原理和算法:https://segmentfault.com/a/11...
- 《MySQL技術內幕 InnoDB存儲引擎》 1.3節
- mysql清空表數據的兩種方式和區別:https://segmentfault.com/a/11...
- Mysql 中 MyISAM 和 InnoDB 的區別有哪些?:https://www.zhihu.com/questio...
- MySQL存儲引擎MyISAM與InnoDB區別總結整理:https://blog.csdn.net/xlgen15...
- MySQL InnoDB的存儲文件:https://blog.csdn.net/chenjia...