MySQL MyISAM儲存引擎

2020-07-16 10:05:29
MyISAM 儲存引擎是 MySQL 中常見的儲存引擎,曾(MySQL 5.1及之前版本)是 MySQL 的預設儲存引擎。

MyISAM 是基於 ISAM 儲存引擎發展起來的。實際上那會還沒有儲存引擎的概念,ISAM 只是一種演算法,或者說是資料的處理方式。如同 SQL Server/Oracle 這類產品一樣,MySQL 對表物件的管理方式只有一種。隨著 MySQL 架構的不斷發展和演進,最終才引入外掛式儲存引擎的概念,ISAM 也進化為 MyISAM 並一直作為 MySQL 資料庫的預設儲存引擎,直到 MySQL 5.5 版本才被 InnoDB 引擎取代了預設儲存引擎的地位。

下面主要從優缺點和物理儲存等方面來介紹 MyISAM 儲存引擎。

優缺點

作為 MySQL 最早的儲存引擎之一,MyISAM 有一些已經開發出來很多年的特性,可以滿足使用者的實際需求。例如全文索引、壓縮、空間函數(GIS)等。但 MySQL 官方的重心早就不在 MyISAM 引擎上了,所以近些年來,MyISAM 一直沒有很大的改進,也存在著許多的缺陷。

優點

  • 占用空間小
  • 存取速度快,對事務完整性沒有要求或以 SELECT、INSERT 為主的應用基本上都可以使用這個引擎來建立表
  • 可以配合鎖,實現作業系統下的複製備份
  • 支援全文檢索(InnoDB 在 MySQL 5.6 版本以後也支援全文檢索)
  • 資料緊湊儲存,因此可獲得更小的索引和更快的全表掃描效能。

1. 加鎖與並行

MyISAM 對整張表加鎖,而不是針對行。讀取時會對需要讀到的所有表加共用鎖,寫入時對表加排他鎖。但是在表有讀取查詢的同時,也可以往表中插入新的記錄(這被稱為並行插入)。

2. 修復

對於 MyISAM 表,MySQL 可以手工(執行命令 CHECK TABLE tablename)或者自動執行檢查和修復(執行命令 REPAIR TABLE tablename)操作,但這裡說的修復和事務恢復以及崩潰修復是不同的概念。

另外,如果 MySQL 伺服器已經關閉,也可以通過 myisamchk 命令列工具進行檢查和修復操作。

3. 索引特性

MyISAM 支援以下 3 種型別的索引:

1)B-Tree 索引

B-Tree 索引,顧名思義,就是所有的索引節點都按照 balance tree 的資料結構來儲存,所有的索引資料節點都在葉節點。

2)R-Tree 索引

R-Tree 索引的儲存方式和 b-tree 索引有一些區別,主要設計用於為儲存空間和多維資料的欄位做索引,所以對於目前的 MySQL 版本來說,也僅支援 geometry 型別的欄位作索引。

3)Full-text 索引

Full-text 索引就是全文索引,它的儲存結構也是 b-tree。主要是為了解決需要用 like 查詢時的低效問題。

MyISAM 上面三種索引型別中,最經常使用的就是 B-Tree 索引了,偶爾會使用到 Full-text,但是 R-Tree 索引一般系統中都是很少用到的。另外 MyISAM 的 B-Tree 索引有一個較大的限制,那就是參與一個索引的所有欄位的長度之和不能超過 1000 位元組。

缺點

  • 不支援事務的完整性和並行性
  • 不支援行級鎖,使用表級鎖,並行性差
  • 主機宕機後,MyISAM表易損壞,災難恢復性不佳
  • 資料庫崩潰後無法安全恢復
  • 只快取索引,資料的快取是利用作業系統緩衝區來實現的,可能會引發過多的系統呼叫,且效率不佳

物理儲存

MyISAM 儲存引擎的表在資料庫中被儲存成 3 個物理檔案,檔名與表名相同。擴充套件名為 frm、MYD 和 MYI。其中:
  • frm 為擴充套件名的檔案儲存表的結構;
  • MYD 為擴充套件名的檔案儲存資料,其是 MYData 的縮寫;
  • MYI 為擴充套件名的檔案儲存索引,其是 MYIndex 的縮寫。不管表有多少索引,都是存放在同一個 .MYI 檔案中。

MyISAM 型別的資料檔案和索引檔案可以放置在不同的目錄,平均分布 IO,以此來獲得更快的速度。

要指定索引檔案和資料檔案的路徑,需要在建立表的時候通過 DATA DIRECTORY 和 INDEX DIRECTORY 語句指定,也就是說不同 MyISAM 表的索引檔案和資料檔案可以放置到不同的路徑下。檔案路徑需要是絕對路徑,並且具有存取許可權。

雖然每一個 MyISAM 的表資料都存放在字尾名為 .MYD 的檔案中,但是每個檔案的存放格式可能並不完全一樣。因為 MyISAM 支援 3 種不同的資料存放格式,即靜態型、動態型和壓縮型。

1)靜態型

靜態型為 MyISAM 儲存引擎的預設儲存格式,其欄位是固定長度,這樣每個記錄都是固定長度的,這種儲存方式儲存非常迅速,容易快取,出現故障容易恢復。缺點是占用的空間比動態表多。靜態型的表的資料在儲存的時候會按照列的寬度定義去補足空格,但是在應用存取的時候並不會得到這些空格,空格在返回給應用之前就被去掉了。

需要注意的是,如果需要儲存的內容後面本來就帶有空格,那麼在返回結果的時候也會被去掉。這一點開發人員在編寫程式的時候需要特別注意,因為靜態表是預設的儲存格式,開發人員可能並沒有意識到這一點,從而丟失了尾部的空格。

2)動態型

動態型包含變長欄位,記錄的長度不是固定的。這樣儲存的優點是占用的空間相對較少,但是頻繁的更新刪除記錄會產生碎片,需要定期執行 OPTIMIZE TABLE 語句或 myisamchk -r 命令來改善效能,並且出現故障的時候恢復相對比較困難。

3)壓縮型

與上面兩種格式相比,壓縮型的錶就顯得特殊一些。壓縮型的表需要使用 myisampack 工具建立,解壓縮則用另外的 myisamchk 命令。壓縮表是制度的,不支援新增或修改記錄。

壓縮表是基於靜態或動態格式表的,優點在於佔用的磁碟空間非常小,可以減少磁碟 I/O,從而提升查詢效能。因為每個記錄都是被單獨壓縮的,所以只有非常小的開支。

理論上,MyISAM 儲存引擎的表可以被多個資料庫範例同時使用同時操作,但是一般不建議這樣做,關於這點,MySQL 官方的使用者手冊中也有提到,建議盡量不要在多個 mysqld 之間共用 MyISAM 儲存檔案。

如果表在建立並匯入資料以後,不會再進行修改操作,這樣的表或許適合採用 MyISAM 壓縮表。