MyISAM 和 InnoDB 都是 MySQL 數(shù)據(jù)庫的數(shù)據(jù)庫引擎,其中 MyISAM 是 5.5 版本之前的默認(rèn)引擎,而 5.5 版本之后,MySQL 引入了InnoDB 并且作為其默認(rèn)的數(shù)據(jù)庫引擎。
01. 鎖
MyISAM 只支持表級(jí)鎖(table-level locking),也就是任何 CRUD 的操作都會(huì)給表加上鎖,而 InnoDB 則支持表級(jí)鎖和行級(jí)鎖(row-level locking),默認(rèn)是行級(jí)鎖。
Innodb 的行級(jí)鎖又分幾種:共享鎖(S),排它鎖(X),意向共享鎖(IS),意向排他鎖(IX);如果 SQL 語句沒有使用索引,并且又不能確定操作的行,這個(gè)時(shí)候就會(huì)鎖表;即使在查詢條件中使用了索引字段,但是如果 MySQL 認(rèn)為全表掃描的效率更高,這時(shí)候也會(huì)使用表鎖,所以還是要通過執(zhí)行計(jì)劃確認(rèn)是否真正使用到了索引。
02. 事務(wù)
MyISAM 強(qiáng)調(diào)的是性能,但是不支持事務(wù);
Innodb 是支持事務(wù)的,事務(wù)級(jí)別包括未提交讀(Read uncommitted),已提交讀(Read committed),可重復(fù)讀(Repeatable read),可序列化(Serializable);
而不支持事務(wù)可能會(huì)導(dǎo)致:數(shù)據(jù)更新丟失、臟讀、不可重復(fù)讀等等;另外事務(wù)可以保障數(shù)據(jù)庫崩潰后的安全恢復(fù)。
03. 外鍵
MyISAM 不支持外鍵,Innodb 支持外鍵。
04. 數(shù)據(jù)庫文件
MyISAM 的數(shù)據(jù)庫文件屬于堆表,每個(gè)表在磁盤上都有三個(gè)文件,frm(存儲(chǔ)表定義)、myd(存儲(chǔ)表數(shù)據(jù))、myi(存儲(chǔ)表索引);
InnoDB 分為表空間數(shù)據(jù)文件和日志文件;其中數(shù)據(jù)文件用于保存數(shù)據(jù)和索引,它又有兩種存儲(chǔ)方式,共享表空間存儲(chǔ)和多表空間存儲(chǔ);如果是共享表空間,那么所有表的數(shù)據(jù)文件和索引文件都保存在同一個(gè)表空間中,如果是多表空間,那么每個(gè)表都有一個(gè)表空間文件,用于存儲(chǔ)數(shù)據(jù)和索引。
05. 索引
MyISAM 使用非聚集索引,也就是索引和數(shù)據(jù)分開存儲(chǔ),索引保存的是數(shù)據(jù)文件的指針;也就是說,主鍵索引和非主鍵索引的葉子節(jié)點(diǎn)都是數(shù)據(jù)文件的指針。
InnoDB 使用聚集索引,也就是索引和數(shù)據(jù)存在一個(gè)文件中;必須要有主鍵;不過如果使用非主鍵索引的話,需要兩次查詢,先查詢到主鍵,然后再通過主鍵查詢到數(shù)據(jù);也就是說,主鍵索引的葉子節(jié)點(diǎn)是數(shù)據(jù)文件,非主鍵索引的葉子節(jié)點(diǎn)是主鍵的值。
另外著重指出,InnoDB 必須有主鍵,MyISAM 可以沒有。
06. count()
MyISAM 保存有表的總行數(shù),如果使用 select count(*) from table,直接取出該值,效率更高;
InnoDB 沒有保存表的總行數(shù),如果使用 select count(*) from table,需要遍歷整個(gè)表;
當(dāng)然如果是加了 where 條件的話,兩種引擎都需要進(jìn)行掃描。
我將持續(xù)分享Java開發(fā)、架構(gòu)設(shè)計(jì)、程序員職業(yè)發(fā)展等方面的見解,希望能得到你的關(guān)注。