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