数据库做为存储数据的仓库,可能你们会想,关系型数据库把咱们的数据一行一行地存储不就完事了吗?哪里又冒出个存储引擎呢?mysql
之因此有多个存储引擎,是由于咱们对表的使用场景并不老是相同的,有时候可能咱们须要频繁的select
和insert
操做,而有的时候可能须要频繁的update
操做。这个时候,不一样引擎的数据表table
就有着不一样的性能了。sql
engine
不一样,数据库把数据data
保存至本地的方式(文件的结构)是不同的,物理结构影响着数据的操做。BTree
索引。transaction
操做。目前,只有InnoDB
引擎支持事务操做。须要说明的是,引擎是针对数据表table
而言的,也就是说咱们讨论的是一张数据表以何种引擎的方式来进行数据存储。数据库
咱们能够查看MySQL数据库支持的引擎以及相应的说明。安全
命令:show engines;
工具
在MySQL里面,咱们主要会使用到的引擎有InnoDB
(默认引擎)、MyISAM
、 MRG_MYISAM
(原名MERGE
) 、MEMORY
。其余引擎可能非专业DBA
接触不到,因此接下来的存储引擎将围绕上面4个展开。性能
顺便说一句,咱们平常绝大部分的都是InnoDB
和MyISAM
引擎。固然,也有一些非官方的引擎,以其高性能而流行,好比说:TokuDB
,它有多项性能指标吊打InnoDB
。spa
table
所使用的引擎命令:rest
show create table userinfo \G; # \G格式化输出
上面的命令,使用查看建表语句,能够查看数据表使用的引擎,固然咱们默认的都是InnoDB
。code
命令:对象
create table tb1( ... ... )engine=MyISAM default charset=utf8;
命令:
alter table t1 engine=InnoDB;
特色 | InnoDB | MyISAM | MRG_MYISAM(原MERGE) | MEMORY |
---|---|---|---|---|
存储大小限制 | 有 | 64TB | 没有 | 有 |
事务安全 | 支持 | |||
锁机制 | 行锁、表锁 | 表锁 | 表锁 | 表锁 |
BTree索引 | 支持 | 支持 | 支持 | 支持 |
Hash索引 | 支持 | |||
fulltext索引 | 支持 | |||
集群索引 | 支持 | |||
数据可压缩 | 支持 | |||
空间使用 | 高 | 低 | ||
内存使用 | 高 | 低 | ||
批量插入的速度 | 高 | |||
支持外键 | 支持 |
咱们说过,平常中使用最多的是InnoDB
和MyISAM
引擎,从上表能够看出,这2者互有长处与短板。所以,咱们要根据业务场景来选择合适的引擎。
InnoDB
引擎InnoDB
引擎很重要的2项功能(也是独有)是支持事务 以及支持外键 。
事务的重要性不言而喻,金融上重要的转帐、交易等操做,为了应对突发事故如停电,须要对数据的操做具备原子性。==事务的具体内容,放置另外一篇章进行讲解==。 这里咱们须要知道,对于涉及到事务的数据表,咱们只能选择InnoDB
引擎来存储。
外键是一种主从的对应关系。只有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) );
下面咱们来复习如下外键相关的知识:
data
中的外键列的值必须在主表中存在。换句话说,咱们想要销售一本新书唐吉坷德
,那么在bookmarket
中就必须有这本书,咱们是不能销售没有货源的书的。这个操做的名称很差取,咱们理解仍是很好理解的。在对主表的数据进行CURD
中的删除和更新时,咱们的从表应该作出哪些相应的操做呢?
咱们能够选择的方案有3种:
RESTRICT
或NO ACTION
,这也是未指定时,默认的设置,即on update restrict on delete restrict
。CASCADE
NULL
。SET 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;
该点水平不够。
MyISAM
引擎在5.5版本以前,MySQL的默认引擎就是这个,使用的也很普遍。它的优势在于访问速度快,适合常常进行select
和insert
操做的场景。缺点就是不支持事务和外键。
每一个MyISAM
表在物理上存储3个文件,分别是:存储表定义、存储数据、存储索引。
适合常常须要进行select
和insert
操做的表。
MyISAM
表支持3种存储格式,分别是静态表(默认)、动态表、压缩表。
咱们建立一个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
表的用武之地了。咱们能够将全部的分表聚合在一块儿,这样就可以对全部数据进行操做了。
CURD
操做由于这张表只提供一个容器的功能,因此MRG_MYISAM
表的CURD
操做和传统意义表的操做是不同的。
create
,定义各个分表的聚合。select
、update
都是操做其内部的分表。delete
只是删除该表的定义,不影响内部的分表。insert
,须要指定数据插入的表,insert_method
的可选值只能是first
和last
和no
,no
表示不能执行插入操做,默认也是no
。咱们先生成2张MyISAM
表,而后生成一个MRG_MYISAM
表,包含前面2个分表。这里咱们指定insert_method
为last
。
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
中。
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 table
、drop table
等。