mysql儲存引擎簡介
mysql儲存引擎簡介
什麼是儲存引擎
mysql儲存引擎是資料庫如何儲存資料、怎樣建立索引以及如何查詢更新資料等技術的實現方法,資料通過使用不同的技術儲存在檔案中,使用不同的儲存機制、索引方式來提供不同的功能。在mysql這種關係型資料中心來說,資料是以表的方式來儲存的,因此,簡單點來說,儲存引擎就是儲存和操作此表的型別。
mysql中有多種儲存引擎,使用命令:show engines 可以檢視當前版本支援的儲存引擎。
mysql> show engines; +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ | InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL | +--------------------+---------+----------------------------------------------------------------+--------------+------+------------+ 9 rows in set (0.00 sec)
從結果來看,我們可以看到只有InnoDB是支援事務的,並且是mysql 的預設儲存引擎。下面分別介紹幾種常見的儲存引擎。
儲存引擎的種類
InnoDB
InnoDB是MySQL5.5版本及以上的預設儲存引擎,也是最重要,使用最廣泛的儲存引擎,它主要有以下幾種特點:
- 是mysql存貯引擎中唯一支援事務的,採用MVCC支援高併發,並且實現了四個標準的隔離級別,預設級別為REPEATABLE READ(可重複讀)。
- 表基於聚簇索引建立
- 支援外來鍵
- 支援行鎖,不過要基於索引,如果是全表掃描的話,仍然是表鎖
InnoDB檔案結構:
.frm與表相關的元資料資訊都存放在frm檔案,包括表結構的定義資訊等;
獨享表空間儲存方式使用.ibd檔案,並且每個表一個ibd檔案;共享表空間儲存方式使用.ibdata檔案,所有表共同使用一個ibdata檔案;
InnoDB使用B+Tree的方式儲存索引,Innodb的一個表可能包含多個索引,每個索引都使用B+樹來儲存。而索引包括聚集索引和非聚集索引(二級索引),聚集索引使用表的主鍵作為索引鍵,包含表的所有欄位。非聚集索引只包含索引鍵和聚集索引鍵(主鍵)的內容,不包括其他欄位。每一個索引都是一棵B+樹,每棵B+樹由很多頁面組成,而每個頁面大小一般為16K。
我們通過下圖看下錶聚集索引和非聚集索引的差別:
聚集索引將索引和資料行儲存在同一個B-Tree中,查詢通過聚集索引可以直接獲取資料
非聚集索引的葉子節點中儲存的不是指向行的物理指標,而是行的主鍵值。當通過聚集索引查詢行,儲存引擎需要在聚集索引中找到相應的葉子節點,獲得行的主鍵值,然後使用主鍵去聚簇索引中查詢資料行,這需要兩次B-Tree查詢。
MyISAM
MyISAM提供了大量的特性,包括全文索引、壓縮、空間函式等,主要有以下特點:
- 不支援事務,不支援行鎖,支援表鎖,讀取時會對需要讀取到的所有表加共享鎖,寫入時則對錶加排他鎖。
- 奔潰後無法安全修復,可以手工或者自動檢查和修復,但是可能導致一些資料的丟失,並且修復工作非常慢。
- MyISAM會將表儲存在兩個檔案中,資料檔案和索引檔案,分別以 .MYD和 .MYI為副檔名
- 支援全文索引,即使是BOLB或者TEXT等長欄位,也可以基於前500個字元建立索引。
每個MyISAM在磁碟上儲存成三個檔案:
.frm檔案:與表相關的元資料資訊都存放在frm檔案,包括表結構的定義資訊等。
.myd檔案:用於儲存myisam表的資料
.myi檔案:,用於儲存myisam表的索引相關資訊
MyISAM索引檔案.MYI (MYIndex)
和資料檔案.MYD (MYData)
是分離的,索引檔案僅儲存記錄所在頁的指標(物理位置),通過這些地址來讀取頁,進而讀取被索引的行。
主鍵索引跟非主鍵索引的結構是一樣:
樹中葉子儲存的是對應行的物理位置。通過該值,儲存引擎能順利地進行回表查詢,得到一行完整記錄。同時,每個葉子頁也儲存了指向下一個葉子頁的指標。從而方便葉子節點的範圍遍歷。
- MyISAM引擎適用的生產業務場景:
- 不需要事務支援的業務
- 一般為讀資料比較多的應用,讀寫都頻繁場景不適合
- 讀寫併發訪問都相對較低的業務
- 對資料一致性要求不是很高的業務。
- 中小型的網站部分業務會用。
CSV引擎
CSV儲存引擎可以將csv檔案作為mysql的表進行處理。儲存格式就是普通的csv檔案,資料以文字方式儲存在檔案中,所有的列必須都是不能為NULL的,不支援索引,可以直接對檔案進行編輯。
在mysql中新建一張表,以CSV為儲存引擎,插入一條資料:
mysql> insert into csvtest (id,name) values (1,"mike");
使用命令檢視檔案儲存位置:
mysql> show global variables like "%datadir%";
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.01 sec)
開啟儲存檔案,檢視csv檔案
[root@localhost shoes]# cat csvtest.CSV
1,"mike"
csv檔案可以直接修改,我們向表中插入幾條記錄
[root@localhost shoes]# vi csvtest.CSV
1,"mike"
2,"jack"
3,"Daniel"
重新整理表,然後檢視資料
mysql> flush tables;
Query OK, 0 rows affected (0.51 sec)
mysql> select * from csvtest;
+----+--------+
| id | name |
+----+--------+
| 1 | mike |
| 2 | jack |
| 3 | Daniel |
+----+--------+
3 rows in set (0.00 sec)
根據CSV的特性,可以在資料庫執行時複製或者到匯出檔案,可以將Excel等電子表格中的資料儲存為CSV檔案,然後複製到MySQL的目錄下面,就能在MySQL中開啟使用。外部程式也可以從表的資料檔案中讀取CSV格式的資料,因此CSV引擎可以作為資料交換的一種機制。
Memory
Memory儲存引擎使用存在於記憶體中的內容來建立表,Memory表至少比MyISAM表要快一個數量級,因為所有的資料都儲存在記憶體中,不需要進行磁碟I/O,Meomory表的結構在重啟後還會保留,但是資料會丟失。Memory表支援Hash索引,是表級鎖,因此併發寫入的時候效能較低,並且不支援BLOB和TEXT型別的列,每行長度固定,即使指定了varchar型別,但是實際儲存的時候仍然會轉換成char。
Memory適用於下幾種場景:
- 用於查詢或者對映表
- 用於快取週期性聚合的資料,內容變化不頻繁的資料
- 用於儲存資料分析中產生的中間資料
InnoDB和MyISAM的比較
- InnoDB支援事務,MyISAM不支援事務
- InnoDB支援行鎖,表鎖,MyISAM只支援表鎖,因此MyISAM不會發生死鎖,但是InnoDB會。
- 接上面一點,由於鎖級別的問題,MyISAM併發效率比InnoDB低
- InnoDB支援外來鍵,而MyISAM不支援
- 索引結構有區別,InnoDB有聚簇索引和非聚簇索引,聚簇索引的葉子節點儲存了資料,MyISAM是非聚簇索 引,索引和資料檔案是分離的,索引儲存的是資料檔案的指標。
- Innodb儲存檔案有frm、ibd,而Myisam是frm、MYD、MYI。
- 還有一個區別是查詢總數,InnoDB不儲存表的具體行數,select count(*)的時候需要全表掃描,而 MyISAM用一個變數儲存了整個表的行數,執行上述語句時只需要讀出該變數即可,速度很快
總結:選擇合適的引擎
MySQL有多種引擎,怎麼基於業務規則與資料特點去選擇呢?大部分情況下,InnoDB都是比較合適的選擇,否則也不會是預設的儲存引擎了。因此,除非是需要用到InnoDB不具備的特性並且沒有其他辦法替代,否則都應該優先選擇InnoDB,像需要支援事務,線上熱備份、奔潰恢復等使用InnoDB都是非常正確的選擇