Mysql-存儲引擎特性與選擇

一、基本概念

MySQL中有存儲引擎的概念,每張表可以對應一種存儲引擎。在使用者看來,表就是用來存取數據,而底層數據在磁盤上的組織、查詢數據時如何索引、表對使用者支持的功能等則由該表對應的存儲引擎來做出規範。

不同的存儲引擎有不同的特性,包括存儲空間大小限制、支持的功能、存取速度、空間利用率也不盡相同,在創建表時,用戶可針對不同的業務需求,自由選擇最適合的存儲引擎,這種插件式存儲引擎是MySQL數據庫最重要的特徵之一。

可通過show engines來查看數據庫支持的引擎(下面是Server version: 5.5.50 MySQL Community Server (GPL)):

mysql> show engines\G
*************************** 1. row ***************************
      Engine: FEDERATED
     Support: NO
     Comment: Federated MySQL storage engine
Transactions: NULL
          XA: NULL
  Savepoints: NULL
*************************** 2. row ***************************
      Engine: MRG_MYISAM
     Support: YES
     Comment: Collection of identical MyISAM tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 3. row ***************************
      Engine: MyISAM
     Support: YES
     Comment: MyISAM storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 4. row ***************************
      Engine: BLACKHOLE
     Support: YES
     Comment: /dev/null storage engine (anything you write to it disappears)
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 5. row ***************************
      Engine: CSV
     Support: YES
     Comment: CSV storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 6. row ***************************
      Engine: MEMORY
     Support: YES
     Comment: Hash based, stored in memory, useful for temporary tables
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 7. row ***************************
      Engine: ARCHIVE
     Support: YES
     Comment: Archive storage engine
Transactions: NO
          XA: NO
  Savepoints: NO
*************************** 8. row ***************************
      Engine: InnoDB
     Support: DEFAULT
     Comment: Supports transactions, row-level locking, and foreign keys
Transactions: YES
          XA: YES
  Savepoints: YES
*************************** 9. row ***************************
      Engine: PERFORMANCE_SCHEMA
     Support: YES
     Comment: Performance Schema
Transactions: NO
          XA: NO
  Savepoints: NO
9 rows in set (0.01 sec)

在創建表時,若不指定存儲引擎,則使用默認存儲引擎,MySQL中默認參數均有對應的變量名,可以通過

show variables [like 'pattren'];

來顯示,要查看默認存儲引擎,可以這樣:

mysql> show variables like '%engine%';
+---------------------------+--------+
| Variable_name             | Value  |
+---------------------------+--------+
| default_storage_engine    | InnoDB |
| engine_condition_pushdown | ON     |
| storage_engine            | InnoDB |
+---------------------------+--------+

其中default_storage_engine即爲默認存儲引擎。

 

  • 創建一張未指定存儲引擎的表:
create table if not exists without_engin(
`id` int not null primary key auto_increment
)charset utf8;

可通過show create table 語句查詢這張表的存儲引擎:

mysql> show create table without_engin\G
*************************** 1. row ***************************
       Table: without_engin
Create Table: CREATE TABLE `without_engin` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

其中ENGINE=InnoDB顯示該表的存儲引擎爲InnoDB,即用的默認引擎。

  • 創建表時指定存儲引擎:
create table with_engin(
id int
)engine=MyISAM charset=utf8;

查看:

mysql> show create table with_engin\G
*************************** 1. row ***************************
       Table: with_engin
Create Table: CREATE TABLE `with_engin` (
  `id` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8

存儲引擎爲MyISAM。

  • 修改表的存儲引擎
alter table with_engin engine = innodb;

查看:

mysql> show create table with_engin\G
*************************** 1. row ***************************
       Table: with_engin
Create Table: CREATE TABLE `with_engin` (
  `id` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8

二、各種存儲引擎特性

各存儲引擎特性如下表:

特點 MyISAM InnoDB MEMORY MERGE NDB
存儲限制 64TB 沒有
事務安全   支持      
鎖機制 表鎖 行鎖 表鎖 表鎖 表鎖
B樹索引 支持 支持 支持 支持 支持
哈希索引      支持    
全文索引 支持        
集羣索引   支持      
數據緩存   支持 支持   支持
索引緩存 支持 支持 支持 支持 支持
數據可壓縮 支持        
空間使用 N/A
內存使用 中等
批量插入速度
支持外鍵   支持      

可以看到不同的存儲引擎可以提供不同的功能、存取性能,所以在設計表的時候,要根據實際的應用場景,選擇合適的存儲引擎以優化系統性能。接下來主要MyISAM、InnoDB、MEMORY和MERGE。

1.MyISAM

特性:不支持事務、不支持外鍵、插入速度快、支持全文索引。
優勢:訪問速度快。
適用場景:1.對事務完整性沒有要求 2.以插入和查詢爲主的應用。

存儲方式:每個使用MyISAM引擎穿件的表在磁盤上存儲成3個文件,其文件名與表名相同,擴展名分別爲

 

  •     .frm (存儲表定義)
  •     .MYD(存儲數據)
  •     .MYI(存儲索引)

我們創建一張表,再插入數據

create table with_myisam_engin(
id int not null primary key auto_increment
)engine=MyISAM charset=utf8;
mysql> insert into with_myisam_engin values (null), (null);
Query OK, 2 rows affected (0.00 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from with_myisam_engin;
+----+
| id |
+----+
|  1 |
|  2 |
+----+

想要查看數據文件的位置,可通過以下命令:

mysql> show global variables like "%datadir%"
    -> ;
+---------------+---------------------------------------------+
| Variable_name | Value                                       |
+---------------+---------------------------------------------+
| datadir       | C:\ProgramData\MySQL\MySQL Server 5.5\Data\ |
+---------------+---------------------------------------------+

這裏的ProgramData可能找不到,因爲是隱藏文件,可以設置顯示隱藏文件找到該文件夾,到該文件夾下,可以看到

其中的每個文件夾都對應我們的一個database,剛纔創建的表在以prac命名的datebase下,表名爲with_myisam_engin

三個文件的數據均是以二進制形式存儲,表中已經插入數據1、2,因爲數據單獨存在於.MYD文件中,可以查看下該文件中的內容

可以看到01 02兩個值。因爲三個文件分別保存了表的結構、數據、存儲定義,可以將這三個文件複製到其他數據庫對應的文件夾下,便可以在其他數據庫訪問該表,這也是使用MyISAM存儲引擎時一種可用的備份方式。

也可將數據文件和索引文件可以放到不同的目錄,平均分配I/O,獲得更快的速度,指定索引文件盒數據文件的路徑,需要在創建表的時候通過DATA DIRECTORY 和 INDEX DIRECTORY語句,這裏指定的路徑必須要是絕對路徑,並且具有訪問權限(寫的權限),筆者在prac文件夾下創建indexs和datas兩個文件夾,並通過以下語句創建一張MyISAM引擎表,指定索引文件、數據文件位置。

create table with_myisam_engin2(
id int not null primary key auto_increment
)engine=MyISAM DATA DIRECTORY='C:/ProgramData/MySQL/MySQL Server 5.5/data/prac/datas'
INDEX DIRECTORY='C:/ProgramData/MySQL/MySQL Server 5.5/data/prac/indexs' charset=utf8;

在windows下面指定文件夾的選項是被忽略的(mysql5.5上,其他版本不知道,在mysql的bug提交網站上可以看到這部分信息

https://bugs.mysql.com/bug.php?id=77773)

存儲格式:MyISAM支持三種不同的存儲格式:

 

  • 靜態(固定長度)表:默認存儲格式,字段是非變長字段,這樣每個記錄都是固定長度的,這種存儲方式的優點是存儲迅速,容易緩存,出現故障容易恢復;缺點是佔用的空間比動態的多。靜態表的數據在存儲時會按照列的寬度定義補足空格,但是在應用訪問的時候並不會得到這些空格,這些空格在返回給應用之前已經去掉,因爲補齊主要是在後面補,所以如果插入的數據尾部本身有空格,再次查詢時會丟掉。
  • 動態表,包含變長字段,記錄不是固定長度的,這樣存儲的優點是佔用空間相對較少,但是頻繁的更新和刪除記錄會產生碎片,需要定期執行OPTIMIZE TABLE語句或myisamchk-r命令來改善性能,並且在出現故障時恢復相對比較困難。
  • 壓縮表由myisampack工具創建,佔據非常小的磁盤空間。因爲每條記錄是被單獨壓縮的,所以只有非常小的訪問開支。

上面提到的myisamchk、myisampack均位於MySQL的暗轉目錄下的bin文件夾下,關於靜態表丟失空格可參看下面的例子

create table lost_space(
name varchar(20) not null
)engine=MyISAM charset=utf8;
insert into lost_space values (" 123"),("123 "),("1 2 3");
select * , length(name) from lost_space;

顯示結果:

+-------+--------------+
| name  | length(name) |
+-------+--------------+
|  123  |            4 |
| 123   |            4 |
| 1 2 3 |            5 |
+-------+--------------+

 

 

 

 

 

 

 

 

 

 

 

(參考資料:《深入淺出MySQL》)

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章