MySQL-浅谈存储引擎

MySQL中的存储引擎

1、前言

数据库做为存储数据的仓库,可能你们会想,关系型数据库把咱们的数据一行一行地存储不就完事了吗?哪里又冒出个存储引擎呢?mysql

之因此有多个存储引擎,是由于咱们对表的使用场景并不老是相同的,有时候可能咱们须要频繁的selectinsert操做,而有的时候可能须要频繁的update 操做。这个时候,不一样引擎的数据表table 就有着不一样的性能了。sql

一、引擎之间的区别

  1. 引擎engine 不一样,数据库把数据data 保存至本地的方式(文件的结构)是不同的,物理结构影响着数据的操做。
  2. 其次,不一样的引擎,所拥有的索引也是不一样的。全部的引擎都拥有BTree 索引。
  3. 还有,不一样的引擎,还意味着是否支持事务transaction 操做。目前,只有InnoDB 引擎支持事务操做。
引擎的说明对象

须要说明的是,引擎是针对数据表table 而言的,也就是说咱们讨论的是一张数据表以何种引擎的方式来进行数据存储。数据库


2、引擎相关操做

一、查看数据库所支持的引擎以及说明

咱们能够查看MySQL数据库支持的引擎以及相应的说明。安全

命令:show engines; 工具

在MySQL里面,咱们主要会使用到的引擎有InnoDB (默认引擎)、MyISAMMRG_MYISAM (原名MERGE) 、MEMORY 。其余引擎可能非专业DBA 接触不到,因此接下来的存储引擎将围绕上面4个展开。性能

顺便说一句,咱们平常绝大部分的都是InnoDBMyISAM 引擎。固然,也有一些非官方的引擎,以其高性能而流行,好比说:TokuDB ,它有多项性能指标吊打InnoDBspa

二、查看数据表table 所使用的引擎

命令:rest

show create table userinfo \G;  # \G格式化输出

上面的命令,使用查看建表语句,能够查看数据表使用的引擎,固然咱们默认的都是InnoDBcode

生成表时指定引擎

命令:对象

create table tb1(
...
...
)engine=MyISAM default charset=utf8;
修改表的引擎

命令:

alter table t1 engine=InnoDB;

3、详细对比各个引擎之间的区别

特色 InnoDB MyISAM MRG_MYISAM(原MERGE) MEMORY
存储大小限制 64TB 没有
事务安全 支持
锁机制 行锁、表锁 表锁 表锁 表锁
BTree索引 支持 支持 支持 支持
Hash索引 支持
fulltext索引 支持
集群索引 支持
数据可压缩 支持
空间使用
内存使用
批量插入的速度
支持外键 支持

咱们说过,平常中使用最多的是InnoDBMyISAM 引擎,从上表能够看出,这2者互有长处与短板。所以,咱们要根据业务场景来选择合适的引擎。


4、各个引擎的介绍

一、InnoDB 引擎

InnoDB 引擎很重要的2项功能(也是独有)是支持事务 以及支持外键

1.1 支持事务

事务的重要性不言而喻,金融上重要的转帐、交易等操做,为了应对突发事故如停电,须要对数据的操做具备原子性。==事务的具体内容,放置另外一篇章进行讲解==。 这里咱们须要知道,对于涉及到事务的数据表,咱们只能选择InnoDB 引擎来存储。

1.2 支持外键

外键是一种主从的对应关系。只有InnoDB 支持外键foreign key ,下面来说解相关的外键操做。

场景假设

如今假设咱们开了一个书店bookstore ,咱们的书源都是由书籍市场bookmarket 提供,因此咱们的书的bookname 应该做为一个外键,参照bookmarket 的主键(bookname)。

模拟

下面咱们来生成上面2个表,并设置相应的主键与外键。

drop table if exists bookmarket;
    create table bookmarket(
    bookname varchar(50),
    price double,
    primary key(bookname)
);

drop table if exists bookstore;
    create table bookstore(
    id int primary key auto_increment,
    bookname varchar(50),
    price double,
    constraint `fk_bookname` foreign key(bookname) references bookmarket(bookname)
);

下面咱们来复习如下外键相关的知识:

  1. 若是咱们想在从表中插入数据,那么data 中的外键列的值必须在主表中存在。换句话说,咱们想要销售一本新书唐吉坷德,那么在bookmarket中就必须有这本书,咱们是不能销售没有货源的书的。
设置主表的DML操做->触发从表操做

这个操做的名称很差取,咱们理解仍是很好理解的。在对主表的数据进行CURD 中的删除更新时,咱们的从表应该作出哪些相应的操做呢?

咱们能够选择的方案有3种:

  1. 从表外键数据存在的状况下,主表不容许删除和更新。RESTRICTNO ACTION ,这也是未指定时,默认的设置,即on update restrict on delete restrict
  2. 主表删除和更新的时候,从表的数据也进行删除和更新。CASCADE
  3. 主表删除和更新的时候,从表的数据对应的列设置为NULLSET NULL
模拟

咱们如今插入一些相关的数据。

insert bookmarket values('book_1',23.42),('book_2',22.2),('book_3',44.1);

insert bookstore values(null,'book_1',30),(null,'book_2',32.2);

而后,咱们以RESTRICT 为例,先修改从表的外键。

alter table bookstore drop foreign key `fk_bookname`;

alter table bookstore add constraint `bookstore_fk_bookname` foreign key(bookname) references 
bookmarket(bookname) on delete restrict on update restrict;

而后,咱们试图删除主表的一行数据:

这里提示,不能删除数据,由于数据被外键所引用。顺便一提,默认状况下,外键会采用on delete restrict on update restrict 的方案。

值得一提的是,当咱们使用外键的时候,最合理的方式应该是on delete restrict on update cascade ,禁止删除,更新同步。

忽视外键

有一个小技巧,那就是当咱们导入多个表的数据时,因为外键的存在,咱们导入表的顺序就有前后之分。那么咱们能够暂时关闭外键检查,这样就无所谓顺序了。

set forign_key_checks=0;
...
...
set forign_key_checks=1;

1.3 存储方式

该点水平不够。

二、MyISAM 引擎

在5.5版本以前,MySQL的默认引擎就是这个,使用的也很普遍。它的优势在于访问速度快,适合常常进行selectinsert 操做的场景。缺点就是不支持事务外键

每一个MyISAM 表在物理上存储3个文件,分别是:存储表定义、存储数据、存储索引。

适用场景

适合常常须要进行selectinsert操做的表。

存储格式

MyISAM 表支持3种存储格式,分别是静态表(默认)、动态表、压缩表。

  1. 静态表,优势是存储速度快,缺点是空间耗费大。并且插入的数据中,定长数据格式的数据列,其字符后面的空格会被删除。
  2. 动态表,优势是空间小,缺点是会产生垃圾碎片。
模拟

咱们建立一个MyISAM 表,有一个列设置为定长数据。(如char),注意varchar是无效的。

drop table if exists isam_t;
    create table isam_t(
    id int,
    name char(12)
)engine=myisam charset=utf8;

接下来,咱们插入数据并验证。

insert isam_t values(2,' tom '),(3,'  kim'),(4,' jol   ');
select id,name,length(name) from isam_t;

咱们能够看出,name 后面的空格已经被去掉了。

三、MRG_MYISAM 引擎

望文生义,MRG_MYISAM 引擎就是将MyISAM 引擎进行合并。它是一组MyISAM 表的组合。它要求这些表的结构彻底相同,MRG_MYISAM 表自己没有数据,它只是一个容器,操做的对象仍是内部的MyISAM 表。

很显然,咱们能够把它当作是一个分表的工具。前面的引擎对比中,咱们知道MyISAM 表的存储大小是有限制的,有时候一张表存储不下全部数据,那么咱们分红多张结构彻底相同的表进行分表存储。这个时候,就是咱们MRG_MYISAM 表的用武之地了。咱们能够将全部的分表聚合在一块儿,这样就可以对全部数据进行操做了。

3.1 表的CURD 操做

由于这张表只提供一个容器的功能,因此MRG_MYISAM 表的CURD 操做和传统意义表的操做是不同的。

  1. create ,定义各个分表的聚合。
  2. selectupdate 都是操做其内部的分表。
  3. delete 只是删除该表的定义,不影响内部的分表。
  4. insert ,须要指定数据插入的表,insert_method的可选值只能是firstlastnono 表示不能执行插入操做,默认也是no
模拟

咱们先生成2张MyISAM 表,而后生成一个MRG_MYISAM 表,包含前面2个分表。这里咱们指定insert_methodlast

drop table if exists bill_2016;
    create table bill_2016(
    id int primary key,
    time date,
    cost double
)engine=myisam;

drop table if exists bill_2017;
    create table bill_2017(
    id int primary key,
    time date,
    cost double
)engine=myisam;

drop table if exists bill_merge;
    create table bill_merge(
    id int primary key,
    time date,
    cost double
)engine=merge union=(bill_2016,bill_2017) insert_method=last;

而后咱们往2张分表中插入数据。

insert bill_2016 values(1,'2016-1-2',22.4),(2,'2016-2-3',44.2);
insert bill_2017 values(100,'2017-4-2',55.2),(102,'2017-6-3',88);

select * from bill_2016;
select * from bill_2017;

咱们查看MRG_MYISAM 表的数据。

能够发现,bill_merge 包含了2个分表的数据。

这时候咱们向bill_merge 插入数据,按照预期,数据应该被插入了第2张表,也就是bill_2017 中。

3.2 存储结构

MRG_MYISAM 表在物理上生成2个文件,其一是存储表定义,其二是包含组合表的信息和插入依据。

四、MEMORY 引擎

MEMORY 引擎使用内存中的数据来建立表,在物理上只对应一个文件。MEMORY 表的访问速度很是快,由于它的数据是放在内存中的,若是服务一旦关掉,那么表中的数据就会丢失。

适用场景

主要用于存储内容变化不频繁的代码表,或者是做为统计操做的中间结果表。相似于一个中间数据存储站,提供给其余操做进行查询。须要注意的是,该表的数据并不会写入磁盘,因此数据的保存须要注意。

模拟

咱们使用bookmarket 表的数据,来生成咱们的MEMORY 表。

create table emp_memory engine=memory
select * from bookmarket;

咱们在生成索引的时候,能够选择Hash或者BTree 这2种。

create index idx_bookname using hash on emp_memory(bookname);
show index from emp_memory;

当咱们不须要MEMORY 表的时候,咱们应该删除从而释放内存。

能够是delete from truncate tabledrop table 等。

相关文章
相关标签/搜索