關(guān)于 MyISAM 引擎,你可能不知道的三件事
存在即合理,雖然在互聯(lián)網(wǎng)公司中 InnoDB 引擎使用較多,但是 MyISAM 引擎的特性自有它自己的使用場(chǎng)景,今天松哥就來(lái)和大家捋一捋 MyISAM,這也是我們 MySQL 進(jìn)階必經(jīng)之路。
1.MyISAM
MyISAM 是 MySQL 的默認(rèn)數(shù)據(jù)庫(kù)引擎(5.5版之前),由早期的 ISAM 所改良。雖然性能極佳,但卻有一個(gè)缺點(diǎn):不支持事務(wù)處理(transaction)。最近幾年,MySQL 逐漸使用 InnoDB 代替了 MyISAM,關(guān)于 InnoDB 和 MyISAM 的歷史糾葛,松哥在上篇文章中(MySQL 體系架構(gòu)簡(jiǎn)介)已經(jīng)和大家介紹過(guò)了,這里就不再贅述。
每一個(gè)使用 MyISAM 存儲(chǔ)引擎的數(shù)據(jù)表,數(shù)據(jù)都會(huì)存放在兩個(gè)文件中 .MYD 和 .MYI,例如我新建一個(gè)使用了 MyISAM 存儲(chǔ)引擎的表,名為 user,然后我們找到 user 表的存放位置,可以看到如下三個(gè)文件:
user.frm:存儲(chǔ)表結(jié)構(gòu)信息,這個(gè)和 MyISAM 引擎沒(méi)有關(guān)系。
user.MYD:存放表數(shù)據(jù)。
user.MYI:存放索引信息。
題外話,如何查看數(shù)據(jù)庫(kù)文件位置?
執(zhí)行命令 show global variables like "%datadir%"; 可以查看數(shù)據(jù)庫(kù)文件位置。
2.特性
那么 MyISAM 都有哪些特性呢?接下來(lái)我們就從如下幾個(gè)方面來(lái)介紹下。
2.1 鎖級(jí)別
基本上大家看到所有講 MyISAM 和 InnoDB 區(qū)別的資料,都會(huì)提到這一點(diǎn),因?yàn)檫@是它倆最為重要的區(qū)別,MyISAM 是表級(jí)鎖(table-level locking),而 InnoDB 支持行級(jí)鎖(row-level locking),也支持表級(jí)鎖,但是默認(rèn)情況下是行級(jí)鎖。
表級(jí)鎖的特點(diǎn)是開(kāi)銷小,加鎖快,不會(huì)出現(xiàn)死鎖,但是鎖定粒度較大,發(fā)生鎖沖突的概率高,而且并發(fā)度也低。
行級(jí)鎖的特點(diǎn)是開(kāi)銷大,加鎖慢,有可能會(huì)出現(xiàn)死鎖,但是它的鎖定粒度小,發(fā)生鎖沖突的概率低,并發(fā)度也高。
根據(jù)鎖的特點(diǎn)來(lái)看,表級(jí)鎖更適合于查詢操作(讀寫(xiě)混合操作執(zhí)行效率較低),而行級(jí)鎖則更適合并發(fā)更新、并發(fā)查詢的應(yīng)用,因?yàn)槲覀兘裉斓闹鹘鞘? MyISAM,所以我們這里就先不討論行級(jí)鎖的問(wèn)題,表級(jí)鎖松哥在上篇文章中也已經(jīng)介紹過(guò)了,這里就不再贅述。沒(méi)看上篇的小伙伴可以參考:MySQL 中的表級(jí)鎖很差勁嗎?。
2.2 check/repair
可以通過(guò) check table 命令來(lái)查看 MyISAM 表是否損壞,也可以通過(guò) repair table 命令來(lái)修復(fù)一個(gè)被損壞的 MyISAM 表。
2.3 全文索引
MyISAM 支持全文索引,曾經(jīng)這是它非常重要的一個(gè)特性。因?yàn)閺?MySQL5.6 開(kāi)始,InnoDB 才支持全文索引,在這之前,官方的存儲(chǔ)引擎只有 MyISAM 支持全文索引。
另外需要注意的是,MyISAM 引擎還可以建立前綴索引(InnoDB 也支持),所謂前綴索引說(shuō)白了就是對(duì)文本的前幾個(gè)字符(具體是幾個(gè)字符在建立索引時(shí)指定)建立索引,這樣建立起來(lái)的索引更小,所以查詢更快。這有點(diǎn)類似于 Oracle 中對(duì)字段使用 Left 函數(shù)來(lái)建立函數(shù)索引,只不過(guò) MySQL 的這個(gè)前綴索引在查詢時(shí)是內(nèi)部自動(dòng)完成匹配的,并不需要使用 Left 函數(shù)。
關(guān)于前綴索引,松哥之前已經(jīng)專門寫(xiě)過(guò)文章介紹過(guò)了:
這個(gè) MySQL 索引選擇性有點(diǎn)意思!
2.4 表壓縮
MyISAM 表支持?jǐn)?shù)據(jù)壓縮。
對(duì)于一些很大的只讀表,我們可以對(duì)其進(jìn)行壓縮,這樣可以有效節(jié)省磁盤(pán) IO。MyISAM 表在壓縮的時(shí)候是對(duì)單行數(shù)據(jù)進(jìn)行壓縮的,所以我們并不用擔(dān)心在讀取一行數(shù)據(jù)的時(shí)候會(huì)對(duì)表進(jìn)行解壓。
MyISAM 表壓縮的命令是 myisampack,我們來(lái)看一個(gè)簡(jiǎn)單案例:
首先進(jìn)入到數(shù)據(jù)庫(kù)文件目錄中查看當(dāng)前的數(shù)據(jù)庫(kù)文件:
然后我們對(duì) user.MYI 文件進(jìn)行強(qiáng)制壓縮:
user.OLD 是壓縮之前的文件備份,其他的是壓縮后的文件,由于松哥這里的樣例數(shù)據(jù)比較少,所以壓縮之后的效果不是很明顯(壓縮后的文件反而變大了,如果數(shù)據(jù)量比較大,就不會(huì)出現(xiàn)這個(gè)問(wèn)題)。
壓縮完成后,我們?cè)賹?duì)數(shù)據(jù)表進(jìn)行操作,如下:
可以看到,只有查詢操作是 OK 的,其他的增刪改都是不可以的,因?yàn)閴嚎s后的 user 表就是一個(gè)只讀表。
2.5 單表限制
在 MySQL5.0 之前,使用 MyISAM 引擎的數(shù)據(jù)表,單表最大大小為 4G,如果我們存儲(chǔ)的數(shù)據(jù)超過(guò)了 4G,就需要在創(chuàng)建表的時(shí)候,手動(dòng)調(diào)整可存儲(chǔ)的數(shù)據(jù)行數(shù)以及每行的數(shù)據(jù)大小。
創(chuàng)建表時(shí)我們可以通過(guò)如下方式修改這兩個(gè)變量:
- CREATE TABLE user2 (
- id INTEGER NOT NULL PRIMARY KEY,
- name CHAR(18) NOT NULL
- ) MAX_ROWS = 1000000000 AVG_ROW_LENGTH = 32;
對(duì)于已存在的表,我們可以通過(guò)如下方法修改這兩個(gè)變量:
- ALTER TABLE user2 MAX_ROWS=1000000000 AVG_ROW_LENGTH=15000;
當(dāng)然,這都是老黃歷了!
在 MySQL5.0 之后,單表的大小限制變成了 256TB,這基本上夠用了。
3.使用場(chǎng)景
非事務(wù)型應(yīng)用(MyISAM 不支持事務(wù))
只讀數(shù)據(jù)(可在表壓縮之后使用)
4.小結(jié)
好啦,幾天就先和小伙伴們扯這么多~
參考資料:
https://zhuanlan.zhihu.com/p/123962424
https://www.cnblogs.com/studyzy/p/4310653.html
本文轉(zhuǎn)載自微信公眾號(hào)「江南一點(diǎn)雨」,可以通過(guò)以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系江南一點(diǎn)雨公眾號(hào)。