7. Mysql数据库-存储引擎

1 存储引擎概述

和大多数的数据库不同, MySQL中有一个存储引擎的概念, 针对不同的存储需求可以选择最优的存储引擎。

存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式 。存储引擎是基于表的,而不是基于库的。所以存储引擎也可被称为表类型。

Oracle,SqlServer等数据库只有一种存储引擎。MySQL提供了插件式的存储引擎架构。所以MySQL存在多种存储引擎,可以根据需要使用相应引擎,或者编写存储引擎。

MySQL5.0支持的存储引擎包含 :InnoDB 、MyISAM 、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等,其中InnoDB和BDB提供事务安全表,其他存储引擎是非事务安全表。

可以通过指定 show engines , 来查询当前数据库支持的存储引擎 :

Mysql数据库-存储引擎_经验分享image-20200616104826352

创建新表时如果不指定存储引擎,那么系统就会使用默认的存储引擎, MySQL5.5之前的默认存储引擎是 MyISAM,5.5之后就改为了InnoDB。

查看Mysql数据库默认的存储引擎 , 指令

show variables like '%storage_engine%';
Mysql数据库-存储引擎_经验分享_02image-20200616105013230

2 存储引擎特性

下面重点介绍几种常用的存储引擎, 并对比各个存储引擎之间的区别, 如下表所示 :

特点 InnoDB MyISAM MEMORY MERGE NDB
存储限制 64TB 没有
事务安全 支持        
锁机制 行锁(适合高并发) 表锁 表锁 表锁 行锁
B树索引 支持 支持 支持 支持 支持
哈希索引     支持    
全文索引 支持(5.6版本后) 支持      
集群索引 支持        
数据索引 支持   支持   支持
索引缓存 支持 支持 支持 支持 支持
数据可压缩   支持      
空间使用 N/A
内存使用 中等
批量插入速度
支持外键 支持        

下面我们将重点介绍最长使用的两种存储引擎:InnoDB、MyISAM , 另外两种 MEMORY、MERGE , 了解即可。

InnoDB

InnoDB存储引擎是Mysql的默认存储引擎。InnoDB存储引擎提供了具有提交、回滚、崩溃恢复能力的事务安全。但是对比MyISAM的存储引擎,InnoDB写的处理效率差一些,并且会占用更多的磁盘空间以保留数据和索引。

InnoDB存储引擎不同于其他存储引擎的特点 :

事务控制

InnoDB是支持事务控制,示例如下:

sql脚本:

create table goods_innodb(
    id int NOT NULL AUTO_INCREMENT,
    name varchar(20NOT NULL,
     primary key(id)
)ENGINE=innodb DEFAULT CHARSET=utf8;

执行sql:

start transaction;
insert into goods_innodb(id,name)values(null,'华为p40');
commit;
Mysql数据库-存储引擎_经验分享_03image-20200616111755137
外键约束

MySQL支持外键的存储引擎只有InnoDB , 在创建外键的时候, 要求主表必须有对应的索引 ,从表在创建外键的时候,关联对应的索引字段。

下面两张表中 , country_innodb是主表 , country_id为主键索引,city_innodb表是从表,country_id字段为外键,对应于country_innodb表的主键country_id 。

-- 主表
create table country_innodb(
    country_id int NOT NULL AUTO_INCREMENT,
    country_name varchar(100NOT NULL,
    primary key(country_id)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 从表
create table city_innodb(
  city_id int NOT NULL AUTO_INCREMENT,
     city_name varchar(50NOT NULL,
     country_id int NOT NULL,
     primary key(city_id),
     key idx_fk_country_id(country_id), -- 设置索引
     CONSTRAINT `fk_city_country` FOREIGN KEY(country_id) REFERENCES -- 设置 country_id 为外键
     country_innodb(country_id) ON DELETE RESTRICT ON UPDATE CASCADE -- 设置 country_id 级联更新
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 插入测试数据
insert into country_innodb values(null,'China'),(null,'America'),(null,'Japan');
insert into city_innodb values(null,'Xian',1),(null,'NewYork',2),(null,'BeiJing',1);
Mysql数据库-存储引擎_经验分享_04image-20200616113807231

删除country_id为1 的country数据:

delete from country_innodb where country_id = 1;
Mysql数据库-存储引擎_经验分享_05image-20200616113721331

更新主表 country表的字段 country_id :

update country_innodb set country_id = 100 where country_id = 1
Mysql数据库-存储引擎_经验分享_06image-20200616113907900

知识小贴士

在创建索引时, 可以指定在删除、更新主表时,对从表进行的相应操作,包括 RESTRICT、CASCADE、SET NULL和 NO ACTION。

RESTRICT和NO ACTION相同, 是指限制在从表有关联记录的情况下, 主表不能更新;

CASCADE表示主表在更新或者删除时,更新或者删除从表对应的记录;

SET NULL 则表示主表在更新或者删除的时候,从表的对应字段被SET NULL 。

针对上面创建的两个表, 从表的外键指定是ON DELETE RESTRICT ON UPDATE CASCADE 方式的, 那么在主表删除记录的时候, 如果从表有对应记录, 则不允许删除, 主表在更新记录的时候, 如果从表有对应记录, 则从表对应更新 。

存储位置

表结构存放在 .frm 文件中, 数据和索引保存在 .ibd 文件中

[root@server01 db2]# ls -ll
total 112
-rw-r----- 1 mysql mysql    61 Feb 13 18:39 db.opt
-rw-r----- 1 mysql mysql  8680 Feb 13 18:40 student.frm  # 表结构文件
-rw-r----- 1 mysql mysql 98304 Feb 13 18:40 student.ibd  # 数据和索引文件
[root@server01 db2]

MyISAM

MyISAM 不支持事务、也不支持外键,其优势是访问的速度快,对事务的完整性没有要求或者以SELECT、INSERT为主的应用基本上都可以使用这个引擎来创建表 。有以下两个比较重要的特点:

不支持事务
create table goods_myisam(
    id int NOT NULL AUTO_INCREMENT,
    name varchar(20NOT NULL,
    primary key(id)
)ENGINE=myisam DEFAULT CHARSET=utf8; -- 指定存储引擎 ENGINE=myisam 

执行sql

insert into goods_myisam values(null,'笔记本');
Mysql数据库-存储引擎_经验分享_07image-20200616115400323

通过测试,我们发现,在 MyISAM 存储引擎中,就算回滚了数据,还是操作后的数据,所以 MyISAM 是没有事务控制的。

文件存储方式

每个MyISAM在磁盘上存储成3个文件,其文件名都和表名相同,但拓展名分别是 :

  • .frm (存储表定义);

  • .MYD(MYData , 存储数据);

  • .MYI(MYIndex , 存储索引);

Mysql数据库-存储引擎_经验分享_08image-20200616121721610

3 存储引擎选择

在选择存储引擎时,应该根据应用系统的特点选择合适的存储引擎。对于复杂的应用系统,还可以根据实际情况选择多种存储引擎进行组合。以下是几种常用的存储引擎的使用环境。

  • InnoDB :  是Mysql的默认存储引擎,用于事务处理应用程序,支持外键。如果应用对事务的完整性有比较高的要求,在并发条件下要求数据的一致性,数据操作除了插入和查询意外,还包含很多的更新、删除操作,那么InnoDB存储引擎是比较合适的选择。InnoDB存储引擎除了有效的降低由于删除和更新导致的锁定, 还可以确保事务的完整提交和回滚,对于类似于计费系统或者财务系统等对数据准确性要求比较高的系统,InnoDB是最合适的选择。
  • MyISAM  :如果应用是以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性、并发性要求不是很高,那么选择这个存储引擎是非常合适的。
  • MEMORY :将所有数据保存在内存中,在需要快速定位记录和其他类似数据环境下,可以提供几块的访问。MEMORY的缺陷就是对表的大小有限制,太大的表无法缓存在内存中,其次是要确保表的数据可以恢复,数据库异常终止后表中的数据是可以恢复的。MEMORY表通常用于更新不太频繁的小表,用以快速得到访问结果。
  • MERGE :用于将一系列等同的MyISAM表以逻辑方式组合在一起,并作为一个对象引用他们。MERGE表的优点在于可以突破对单个MyISAM表的大小限制,并且通过将不同的表分布在多个磁盘上,可以有效的改善MERGE表的访问效率。这对于存储诸如数据仓储等VLDB环境十分合适。