MySQL——存储引擎

Posted 明王不动心

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL——存储引擎相关的知识,希望对你有一定的参考价值。

核心知识点

1.InnoDB:数据和索引存放在单独的文件,聚簇索引,行级锁,事务,MVCC

2.MyISAM:

(1)缺点:不支持事务和表级锁,因为不支持表锁,锁颗粒比较大,因此适合只读和小文件。

(2)文件:数据文件和索引文件以.MYD和.MYI结尾。

(3)压缩表:压缩表不能修改,可以减少磁盘占用,也可以减少磁盘I/O;支持索引,所以只读;记录单独存放,要去单行不需要解压整个表。

3.memory:不需要进行磁盘I/O,查询速度非常快;使用的是表级锁,并发写入能力较低;系统中的临时表,就是使用memory。

 4.Archive:

(1)行级锁和专用缓冲区,所以支持高并发写入。

(2)只支持INSERT和SELECT,SELECT要进行全表扫描,而且只支持串查,当一个人查的时候会阻塞其他人的查询。

(3)会对所有写入的行进行压缩,所以磁盘I/O更少。

(4)适合日志和数据采集

 

在文件系统中,mysql将每个数据库(也可以称之为schema)保存为数据目录下的一个子目录。

创建表时,MySQL会在数据库子目录下创建一个和表同名的.frm文件保存表的定义。

MySQL使用文件系统的目录和文件来保存数据库和表的定义,大小写敏感性和具体的平台密切相关。

一、InnoDB存储引擎

InnoDB是MySQL的默认事务型引擎,也是最重要、最广泛的存储引擎。

它被设计用来处理大量的短期事务,短期事务大部分情况是正常提交的,很好会被回滚。

InnoDB的性能和自动恢复特性,使得它在非事务型存储的需求中也很流行。

除非有特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。

 

InnoDB的数据存储在表空间(tablespace)中,表空间是由InnoDB管理的一个黑盒子,由一些列的数据文件组成

在MySQL4.1以后的版本中,InnoDB可以将每个表的数据和索引存放在单独的文件中

InnoDB也可以使用裸设备作为表空间的存储介质,但现代的文件系统使得裸设备不再是必要的选择。

InnoDB采用MVCC来支持高并发,并且实现了四个标准的隔离级别。其默认级别是REPEATABLE READ(可重复读),并且通过间隙锁策略防止幻读的出现。

间隙锁使得InnoDB不仅仅锁定查询涉及的行,还会对索引中的间隙进行锁定,以防止幻影行的插入。

InnoDB表是基于聚簇索引建立的。InnoDB的索引结构和MySQL的其他存储引擎有很大的不同,聚簇索引对主键查询有很高的性能

不过它的二级索引(secondary index,非主键索引)中必须包含主键列,所以如果主键列很大的话,其他的所有索引都会很大。

因此,若表上的索引较多的话,主键应当尽可能的小。

InnoDB的存储格式是平台独立的,也就是说可以讲数据和索引文件从Intel平台复制到PowerPC 或者Sun SPARC平台。

InnoDB内部做了很多优化,包括从磁盘读取数据时采用的可预测性预读,能够自动在内存创建hash索引以加速读操作的自适应哈希索引,以及能够加速插入操作的插入缓冲区等。

 

二、MyISAM存储引擎

在MySQL5.1及之前的版本,MyISAM是默认的存储引擎。

MyISAM提供了大量的特性,包括全文索引、压缩、空间函数等,但MyISAM不支持事务和行级锁,而且有一个毫无疑问的缺陷就是崩溃后无法安全恢复。

尽管MyISAM引擎不支持事务、不支持崩溃后的安全恢复,但它不是一无是处的。

对于只读的数据,或者表比较小、可以忍受修复操作,则依然可以继续使用MyISAM。

 

(1)存储

MyISAM会将表存储在两个文件中:数据文件和索引文件,分别以.MYD和.MYI为扩展名

MyISAM表可以包含动态或者静态(长度固定)行。MySQL会根据表的定义来决定采用何种行格式。

MyISAM表可以存储的行记录数,一般受限于可用的磁盘空间,或者操作系统中单个文件的最大尺寸。

在MySQL5.0中,MyISAM表如果是变长行,则默认配置只处理256TB的数据,因为指向数据记录的指针长度是6个字节。

而在更早的版本中,指针长度默认是4个字节,所以只能处理4GB的数据。而所有的MySQL版本都支持8字节的指针。

要改变MyISAM表指针的长度(调高或者调低),可以通过修改表的MAX_ROWS和AVG_ROW_LENGTH选项的值来实现,两者相乘就是表可能达到的最大大小。

修改这两个参数会导致重建整个表和表的所有索引。

 

(2)特性

作为MySQL最早的存储引擎之一,MyISAM有一些已经开发出来很多年的特性,可以满足用户的实际需求。

加锁与并发

MyISAM对整张表加锁,而不是针对行。读取时会对需要读到的所有表加共享锁,写入时则对表加排他锁。

但是在表有读取查询的时候,也可以往表中插入新的记录。

 

修复

对于MyISAM表,MySQL可以手工或者自动执行检查和修复操作,但这里说的修复和事务恢复是不同的概念。

执行表的修复可能导致一些数据丢失,而且修复操作是非常慢的。可以通过CHECK TABLE mytable检查表的错误,如果有错误可以通过执行REPAIR TABLE mytable进行修复。

另外,如果MySQL服务器已经关闭,也可以通过myisamchk命令行工具进行检查和修复操作。

 

索引特性

对于MyISAM表,即使是BLOB和TEXT等长字段,也可以基于其前500个字符创建索引。

MyISAM也支持全文索引,这是一种基于分词创建的索引,可以支持复杂的查询。

 

(3)MyISAM压缩表

如果表在创建并导入数据以后,不会再进行修改操作,那么这样的表或采用许适合MyISAM压缩表。

可以使用myisampack对MyISAM表进行压缩(也叫做pack)。压缩表是不能进行修改的(除非先将表解除压缩,修改数据,然后再次压缩)。

压缩表可以极大地减少磁盘空间占用,因此也可以减少磁盘I/O,从而提升查询性能

压缩表也支持索引,但索引也是只读的。以现在的硬件能力,对大多数应用场景,读取压缩表数据时的解压带来的开销影响并不大,而减少I/O带来的好处则要大的多。

压缩时表中的记录是独立压缩的,所以读取单行的时候不需要去解压整个表(甚至也不解压行所在的整个页面)。

 

(4)MyISAM性能

MyISAM引擎设计简单,数据以紧密格式存储,所以在某些场景下的性能很好。

MyISAM有一些服务器级别的性能扩展限制,比如对索引键缓冲区(key cache)的Mutex锁,MariaDB基于段的索引键缓冲区机制来避免该问题。

但MyISAM最典型的性能问题还是表锁的问题,如果你发现所有的查询都长期处于“Locked”状态,那么毫无疑问表锁就是罪魁祸首。

 

 

三、memory引擎

如果需要快速的访问数据,并且这些数据不会被修改,重启以后丢失也没有关系,那么使用Memory表是非常有用的。

Memory表至少比MyISAM表要快一个数量级,因为所有的数据都保存在内存中,不需要进行磁盘I/O

Memory表的结构在重启以后还会保留,但数据会丢失。

Memory表在很多场景可以发挥好的作用:

(1)用于查找(lookup)或者映射(mapping)表

(2)用户缓存周期性聚合数据的结果

(3)用户保存数据分析中产生的中间数据

 

Memory表支持Hash索引,因此查询操作非常快。虽然Memory表的速度非常快,但还是无法取代传统的基于磁盘的表。

Memory表是表级锁,因此并发写入的性能较低

它不支持BLOB或TEXT类型的列,并且每行的长度是固定的,所以即使指定了VARCHAR列,

实际存储时也会转化成CHAR,这可能会导致部分内存浪费。

如果MySQL在执行查询的过程中需要使用临时表来保存中间结果,内部使用的临时表就是Menory表。

如果中间结果大大超出了Memory表的限制,或者含有BLOB或者TEXT字段,则临时表会转换成MyISAM表。

 

四、NDB集群引擎

2003年,当时的MySQL AB公司从索尼爱立信公司收购了NDB数据库,然后开发了NDB集群存储引擎,作为SQL和NDB原生协议之间的接口。

MySQL服务器、NDB集群存储引擎,以及分布式的、share-nothing的、容灾的、高可用的NDB数据库的组合被称为MySQL集群。

 

五、CSV引擎

CSV引擎可以将普通的CSV文件(逗号分割值的文件)作为MySQL的表来处理,但这种表不支持索引。

CSV引擎可以在数据库运行时拷入或着拷出文件。

可以将Execl等电子表格如那件中的数据存储为CSV文件,然后复制到MySQL数据目录下,就能在MySQL中打开使用。

同样将数据写入到一个CSV引擎表,其他外部程序也能立即从表的数据文件中读取CSV格式的数据。

因此CSV引擎可以作为一种数据交换的机制,非常有用。

mysql> create table info(id int(4) not null ,name char(10) not null) engine = csv;
Query OK, 0 rows affected (0.12 sec)

mysql> insert into info values(1,\'科比\');
Query OK, 1 row affected (0.12 sec)

mysql> insert into info values(2,\'毛线\');
Query OK, 1 row affected (0.00 sec)

mysql> insert into info values(3,\'小鸟\');
Query OK, 1 row affected (0.00 sec)

效果:

 

 

六、Blackhole引擎

Black引擎没有实现任何的存储机制,它会丢弃所有插入的数据,不做任何保证。但是服务器会记录Blackhole表的日志,所以可以用于复制数据到备库,或者只是简单的记录到日志。

这种特殊的存储引擎可以在一些特殊的复制架构和日志审核时发挥作用,但不推荐使用。

 

七、Archive

Archive存储引擎只支持INSERT和SELECT操作,在MySQL5.1之前也不支持索引。

Archive引擎会缓存所有的写并利用zilb对插入的行进行压缩,所以比MyISAM表的磁盘I/O更少

但是每次SELECT查询都需要进行全表扫描。所以ARchive表适合日志和数据采集类应用,这类应用做数据分析时往往需要全表扫面。或者在一些需要更快速的INSERT操作的场合下也可以使用。

 

ARchive引擎支持行级锁和专用的缓冲区,所以可以实现高并发的插入,在一个查询开始知道返回表中存在的所有行数之前,Archive引擎会阻止其他的SELECT执行,以实现一致性读。

另外,也实现了批量插入在完成之前对都操作是不可见的。这种操作模仿了事务和MVCC的一些特性,但Archive引擎不是一个事务型的引擎,而是一个插入和压缩做了优化的简单引擎。

以上是关于MySQL——存储引擎的主要内容,如果未能解决你的问题,请参考以下文章

使用Merge存储引擎实现MySQL分表

使用Merge存储引擎实现MySQL分表

MySQL中innodb引擎分析(初始化)

MySQL视图存储过程与存储引擎

(转)Mysql存储引擎__笔记

查看和修改MySQL数据库表存储引擎