存儲引擎概述
什么是存儲引擎
是數據庫底層軟件組件,數據庫管理系統使用數據索引進行創建、查詢、更新和刪除數據操作。不同的存儲引擎提供不同的存儲機制、索引技巧】鎖定水平等功能,使用不同的存儲引擎可以獲得特定的功能
MySQL5.7支持的存儲引擎
InnoDB、MyISAM、Memory、Merge、Archive、Federated、CSV、BLACKHOLE等。使用show engines語句可以查看系統支持的引擎類型
功能 | MyISAM | MEMORY | InnoDB | Archive |
---|---|---|---|---|
存儲限制 | 256TB | RAM | 64TB | None |
支持事務 | no | no | yes | no |
支持全文索引 | yes | no | no | no |
支持樹索引 | yes | yes | yes | no |
支持哈希索引 | no | yes | no | no |
支持數據緩存 | no | N/A | yes | no |
支持外鍵 | no | no | yes | no |
InnoDB 適用于需要提交、回滾和恢復的事務安全(ACID)能力,并要求實現并發控制,是 MySQL的默認存儲引擎??
MyISAM能夠為數據表的插入和查詢記錄提供較高的處理效率
如果只是臨時存放數據,數據量不大,并且不需要較高的數據安全性,可以選擇將數據保存在內存的 MEMORY 引擎中,MySQL 中使用該引擎作為臨時表,存放查詢的中間結果。
如果只有 INSERT 和 SELECT 操作,可以選擇Archive 引擎,Archive 存儲引擎支持高并發的插入操作,但是本身并不是事務安全的。Archive 存儲引擎非常適合存儲歸檔數據
操作存儲引擎
查看mysql支持的存儲引擎
show engines;
MyISAM 存儲引擎
MyISAM 存儲引擎不支持事務,也不支持外鍵,特點是訪問速度快,對事務完整性沒有要求,以 SELECT、INSERT 為主的應用基本都可以使用這個引擎來創建表。
每個 MyISAM 表在磁盤上存儲成 3 個文件,其中文件名和表名都相同,但是擴展名分別為:
(1)frm(存儲表定義)
(2)MYD(MYData,存儲數據)
(3)MYI(MYIndex,存儲索引)
MyISAM 表還支持 3 種不同的存儲格式:
(1)靜態(固定長度)表
(2)動態表
(3)壓縮表
InnoDB存儲引擎
是MySQL的默認存儲引擎,在下場景中使 用 InnoDB 存儲引擎是最理想的選擇:
(1)更新密集的表:InnoDB 存儲引擎特別適合處理多重并發的更新請求。
(2)事務:InnoDB 存儲引擎是支持事務的標準 MySQL 存儲引擎。
(3)自動災難恢復:與其它存儲引擎不同,InnoDB 表能夠自動從災難中恢復。
(4)外鍵約束:MySQL 支持外鍵的存儲引擎只有 InnoDB。
(5)支持自動增加列 AUTO_INCREMENT 屬性。
Innodb的數據文件:
ibd:數據表的數據文件
frm:數據表的元數據
opt:存儲的是mysql的一些配置信息,如編碼、排序的信息等
修改默認的存儲引擎
創建表,并查看默認用的存儲引擎
創建表,并查看默認用的存儲引擎
mysql> create database auth;
mysql> use auth
mysql> CREATE TABLE t1 (user_name CHAR(16), user_passwd CHAR(48));mysql> show table status from auth where name='t1'\G
通過 alter table 修改
mysql> alter table t1 engine=MyISAM;
mysql> show table status from auth where name='t1'\G
通過 create table 創建表時指定存儲引擎
[root@localhost ~]# vim /etc/my.cnf
[mysqld]
//添加下面語句
default-storage-engine=MyISAM[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# mysql -uroot -ppwd123
mysql> use authmysql> CREATE TABLE t2 (user_name CHAR(16), user_passwd CHAR(48));
mysql> show table status from auth where name='t2'\G
臨時修改默認存儲引擎?
SET default_storage_engine=< 存儲引擎名 >
MyISam和InnoDB實例比較
1:創建兩張表分別以MyIsam和InnoDB作為存儲引擎
create database test;
use test;
create table tm(id int(20) primary key auto_increment,name char(30)) engine=myisam;
create table ti(id int(20) primary key auto_increment,name char(30)) engine=innodb;
mysql> show create table tm\G
mysql> show create table ti\G
2.插入一千萬數據,來比較兩個存儲引擎的存儲效率
創建兩個存儲過程
mysql> create procedure insertm()
begin
set @i=1;
while @i<=10000000
do
insert into tm(name) values(concat("wy",@i));
set @i=@i+1;
end while;
end
$mysql> create procedure inserti()
begin
set @i=1;
while @i<=10000000
do
insert into ti(name) values(concat("wy",@i));
set @i=@i+1;
end while;
end
$mysql> delimiter ;
利用存儲過程向兩個表添加數據
插入(一千萬條)MyIsam存儲引擎的表中的時間如下:mysql> call insertm;Query OK, 0 rows affected (1 min 49.74 sec)插入(一千萬條)InnoDB存儲引擎的表中的時間如下:mysql> call inserti;Query OK, 0 rows affected (13 min 32.96 sec)根據結果得出:MyIsam存儲引擎在寫入方面有優勢
3.查詢數據總數目
InnoDB的SQL語句的分析:
mysql> desc select count(*) from ti\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: tipartitions: NULLtype: index
possible_keys: NULLkey: PRIMARYkey_len: 4ref: NULLrows: 9732352filtered: 100.00Extra: Using index
1 row in set, 1 warning (0.00 sec)
下面是MyIsam(他的數據存儲在其他的表中所以這里是沒有影響行數的)的SQL語句的分析:
mysql> desc select count(*) from tm\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: NULLpartitions: NULLtype: NULL
possible_keys: NULLkey: NULLkey_len: NULLref: NULLrows: NULLfiltered: NULLExtra: Select tables optimized away
1 row in set, 1 warning (0.00 sec)
4.查詢某一范圍的數據
沒有索引的列
mysql> select * from tm where name>"zhangsan100" and name<"zhangsan10000000";
+---------+-----------------+
| id | name |
+---------+-----------------+
| 1000 | zhangsan1000 |
| 10000 | zhangsan10000 |
| 100000 | zhangsan100000 |
| 1000000 | zhangsan1000000 |
+---------+-----------------+
4 rows in set (1.69 sec)mysql> select * from ti where name>"zhangsan100" and name<"zhangsan10000000";
+---------+-----------------+
| id | name |
+---------+-----------------+
| 1000 | zhangsan1000 |
| 10000 | zhangsan10000 |
| 100000 | zhangsan100000 |
| 1000000 | zhangsan1000000 |
+---------+-----------------+
4 rows in set (2.57 sec)mysql> select * from ti where name="zhangsan9999999";
+---------+-----------------+
| id | name |
+---------+-----------------+
| 9999999 | zhangsan9999999 |
+---------+-----------------+
1 row in set (2.15 sec)mysql> select * from tm where name="zhangsan9999999";
+---------+-----------------+
| id | name |
+---------+-----------------+
| 9999999 | zhangsan9999999 |
+---------+-----------------+
1 row in set (0.99 sec)
無索引查詢MyIsam有優勢
有索引的列
mysql> select * from tm where id>10 and id<999999;999988 rows in set (1.96 sec)mysql> select * from ti where id>10 and id<999999;999988 rows in set (0.52 sec)
有索引查詢InnoDB有優勢