Mysql中的存储引擎

一,存储引擎的概念

Mysql中的数据用各种不同的技术存储在文件(或内存)中。这些技术中的每一种技术都使用不同的存储机制,索引技巧,锁定水平并且最终提供广泛的不同的功能和能力。通过选择不同的技术,能够获得额外的速度或者功能,从而改善应用的整体功能。例如,如果你在研究大量的临时数据,你也许需要使用内存Mysql存储引擎。内存存储引擎能够在内存中存储所有的表格数据。又或者,你也许需要一个支持事务处理的数据库(以确保事务处理不成功时数据的回退能力)。这些不同的技术以及配套的相关功能在Mysql中被称为存储引擎(也称作表类型)。Mysql默认配置了许多不同的存储引擎,可以预先设置或者在Mysql服务器中启用。你可以选择适用于服务器,数据库和表格的存储引擎,以便在选择如何存储你的信息,如何检索这些信息以及你需要你的数据结合什么性能和功能的时候为你提供最大的灵活。

关系数据库是用于存储和组织信息的数据结构,可以将表理解为行和列组成的表格,类似于excel的电子表格形式。有的表简单,有的表复杂,有的表根本不用存储任何长期的数据,有的表读取时非常快,但是插入数据时却很差;而我们在实际开发过程中,就可能需要各种各样的表,不同的表,就意味着存储不同类型的数据,数据的处理上也会存在着差异,那么,对Mysql而言,它提供了很多类型的存储引擎(或者说不同的表类型),我们可以根据数据处理的需求,选择不同的存储引擎,从而最大限度的利用Mysql强大的功能。

二,Mysql中查看引擎

1. show engines;    //查看mysql所支持的存储引擎,以及从中得到mysql默认的存储引擎

2. show variables  like '% storage_engine';    //查看mysql默认的存储引擎

3. show create table tablename;    //查看具体某一个所使用的存储引擎

4. show table status from database where name="tablename";

三,Mysql中常用的几种存储引擎:InnoDB, BDB, MyISAM, Memory

1. InnoDB存储引擎

InnoDB是一个健壮的事务型存储引擎,这种存储引擎已经被很多互联网公司使用,为用户操作非常大的数据存储提供了一个强大的解决方案。InnoDB还引入了行级锁定和外键约束,在以下场合下,使用InnoDB是最理想的场合:

(1). 更新密集的表。InnoDB存储引擎特别适合处理多重并发的更新请求

(2). 事务。InnoDB存储引擎是支持事务的标准Mysql存储引擎

(3). 自动灾难恢复。与其他存储引擎不同,InnoDB表能够自动从灾难中恢复

(4). 外键约束。Mysql支持外键的存储引擎只有InnoDB

(5). 支持自动增加列Auto_Increment属性

InnoDB不创建目录,使用InnoDB时,Mysql将在Mysql数据目录下创建一个名为iddata1的10MB大小的自动扩展数据文件,以及两个名为ib_logfile0和ib_logfile1的5MB大小的日志文件。

场景:由于其支持事务处理,支持外键,支持崩溃修复能力和并发控制。如果需要对事务的完整性要求较高(比如银行),要求实现并发控制(比如售票),那选择InnoDB有很大的优势。如果需要频繁的更新,删除操作的数据库,也可以选择InnoDB,因为支持事务的提交(commit)和回滚(rollback)。

2. MyISAM存储引擎

MyISAM拥有较高的插入、查询速度,但不支持事务,也不支持外键。尤其是访问速度快,对事务完整性没有要求或者以select,insert为主的应用基本都可以使用这个引擎来创建表。每个MyISAM在磁盘上存储成3个文件,其中文件名和表名都相同,但是扩展名分别为:

.frm(存储表定义)

MYD(MYData,存储数据)

MYI(MYIndex,存储索引)

数据文件和索引文件可以放置在不同的目录,平均分配IO,获得更快的速度。要指定数据文件和索引文件的路径,需要在创建表的时候通过DATA DIRECTORY和INDEX DIRECTORY语句指定,文件路径需要使用绝对路径。

每个MyISAM表都有一个标志,服务器或myisamchk程序在检查MyISAM数据表时会对这个标志进行设置。MyISAM表还有一个标志用来表名该数据表在上次使用后是不是被正常的关闭了。如果服务器以为宕机或崩溃,这个标志可以用来判断数据表是否需要检查和恢复。如果想让这种检查自动进行,可以再启动服务器时使用--myisam-recover现象。这会让服务器在每次打开一个MyISAM数据表是自动检查数据表的标志并进行必要的修复处理。MyISAM类型的表可能会损坏,可以使用check table语句来检查MyISAM表的健康,并用repair table语句修复一个损坏的MyISAM表。

MyISAM表还支持3种不同的存储格式:

静态(固定长度)表

动态表

压缩表

其中静态表是默认的存储格式。静态表中的字段都是非变长字段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。静态表在数据存储时会根据列定义的宽度定义补足空格,但是在访问时并不会的得到这些空格,这些空格在返回给应用之前已经去掉。同时需要注意:在某些情况下可能需要返回字段后的空格,而使用这种格式时后面的空格会被自动处理掉。

动态表包含变长字段,记录不是固定长度的,这样存储的优点是占用空间较少,但是频繁更新删除记录会产生碎片,需要定期执行optimize table语句或myisamchk -r命令来改善性能,并且出现故障的时候恢复相对比较困难。

压缩表由myisamchk工具创建,占据非常小的空间,因为每条记录都是被单独压缩的,所以只有非常小的访问开支。

(1). 大文件(达到63位文件长度),在支持大文件的文件系统和操作系统上被支持

(2). 当把删除和更新及插入操作混合使用的时候,动态尺寸的行产生更少碎片。这要通过合并相邻被删除的块,以及若下一个块被删除,就扩展下一块自动完成。

(3). 每个MyISAM表最大索引数是64,这可以通过重新编译来改变。每个索引的最大列数是16。

(4). 最大的键长度是1000字节,这也可以通过编译来改变。

(5). BLOB和TEXT列可以被索引,支持FULLTEXT类型的索引,而InnoDB不支持这种类型的索引。

(6). NULL被允许在索引的列中,这个值占每个键的0~1个字节。

(7). 所有数字键值以高字节优先被存储,以允许一个更高的索引压缩。

(8). 每个MyISAM类型的表都有一个AUTO_INCREMENT的内部列,当insert和update操作的时候该列被更新,同时AUTO_INCREMENT列将被刷新。所以说,MyISAM类型表的AUTO_INCREMENT列更新比InnoDB类型的AUTO_INCREMENT更快。

(9). 可以把数据文件和索引文件放在不同目录。

(10). 每个字符列可以有不同的字符集。

(11). 有VARCHAR的表可以固定或动态记录长度。

(12). VARCHAR和CHAR列可以多达64KB。

场景:如果表主要是用于插入新记录和读出记录,那么选择MyISAM能实现处理高效率。

3. MEMORY存储引擎

使用Mysql Memory存储引擎的出发点是速度。为得到最快的响应时间,采用的逻辑存储介质是系统内存。虽然在内存中存储表数据确实会提供很高的性能,但当mysqld守护进程崩溃时,所有的Memory数据都会丢失。获得速度的同时也带来了一些缺陷。它要求存储在Memory表里的数据使用的是长度不变的格式,这意味着不能使用BLOB和TEXT这样的长度可变的数据类型,VARCHAR是一种长度可变的类型,但以为它在Mysql内部当做长度固定不变的char类型,所以可以使用。

一般在以下几种情况下使用Memory内存引擎:

(1). 目标数据较小,而且被非常频繁地访问。在内存中存放数据,所以会造成内存的使用,可以通过参数max_heap_table_size控制Memory表的大小,设置此参数,就可以限制Memory表的最大大小。

(2). 如果数据是临时的,而且要求必须立即可用,那么就可以存放在内存表中。

(3). 存储在Memory表中的数据如果突然丢失,不会对应用服务产生实质的负面影响。

(4). MEMORY表的每个表可以有多达32个索引,每个索引16列,以及500字节的最大键长度

(5). MEMORY存储引擎执行HASH和BTREE缩影

(6). 可以在一个MEMORY表中有非唯一键值

(7). MEMORY支持AUTO_INCREMENT列和对可包含NULL值的列的索引

(8). MEMORY表在所由客户端之间共享(就像其他任何非TEMPORARY表)

(9). MEMORY表内存被存储在内存中,内存是MEMORY表和服务器在查询处理时的空闲中,创建的内部表共享

(10). 当不再需要MEMORY表的内容时,要释放被MEMORY表使用的内存,应该执行DELETE FROM或TRUNCATE TABLE,或者删除整个表(使用DROP TABLE)

Memory同时支持散列索引和B树索引。B树索引的优于散列索引的是,可以使用部分查询和通配查询,也可以使用<、>和>=等操作符方便数据挖掘。散列索引进行“相等比较”非常快,但是对“范围比较”的速度就慢多了,因此散列索引值适合使用在=和<>的操作符中,不适合在<或>操作符中,也同样不适合用在order by子句中。

可以在表创建时利用USING子句指定要使用的版本。例如:

复制代码代码如下:

create table users

(

    id smallint unsigned not null auto_increment,

    username varchar(15) not null,

    pwd varchar(15) not null,

    index using hash (username),

    primary key (id)

)engine=memory;

上述代码创建了一个表,在username字段上使用了HASH散列索引。下面的代码就创建一个表,使用BTREE索引。

复制代码代码如下:

create table users

(

    id smallint unsigned not null auto_increment,

    username varchar(15) not null,

    pwd varchar(15) not null,

    index using btree (username),

    primary key (id)

)engine=memory;

现在mongodb、redis等NOSQL数据库愈发流行,MEMORY存储引擎的使用场景越来越少。

场景:如果需要该数据库中一个用于查询的临时表。

4. MERGE存储引擎

MERGE存储引擎是一组MyISAM表的组合,这些MyISAM表结构必须完全相同,尽管其使用不如其它引擎突出,但是在某些情况下非常有用。说白了,Merge表就是几个相同MyISAM表的聚合器;Merge表中并没有数据,对Merge类型的表可以进行查询、更新、删除操作,这些操作实际上是对内部的MyISAM表进行操作。Merge存储引擎的使用场景。

对于服务器日志这种信息,一般常用的存储策略是将数据分成很多表,每个名称与特定的时间端相关。例如:可以用12个相同的表来存储服务器日志数据,每个表用对应各个月份的名字来命名。当有必要基于所有12个日志表的数据来生成报表,这意味着需要编写并更新多表查询,以反映这些表中的信息。与其编写这些可能出现错误的查询,不如将这些表合并起来使用一条查询,之后再删除Merge表,而不影响原来的数据,删除Merge表只是删除Merge表的定义,对内部的表没有任何影响。

5. ARCHIVE存储引擎

Archive是归档的意思,在归档之后很多的高级功能就不再支持了,仅仅支持最基本的插入和查询两种功能。在MySQL 5.5版以前,Archive是不支持索引,但是在MySQL 5.5以后的版本中就开始支持索引了。Archive拥有很好的压缩机制,它使用zlib压缩库,在记录被请求时会实时压缩,所以它经常被用来当做仓库使用。

场景:由于高压缩和快速插入的特点Archive非常适合作为日志表的存储引擎,但是前提是不经常对该表进行查询操作。

6. CSV存储引擎

使用该引擎的MySQL数据库表会在MySQL安装目录data文件夹中的和该表所在数据库名相同的目录中生成一个.CSV文件(所以,它可以将CSV类型的文件当做表进行处理),这种文件是一种普通文本文件,每个数据行占用一个文本行。该种类型的存储引擎不支持索引,即使用该种类型的表没有主键列;另外也不允许表中的字段为null。csv的编码转换需要格外注意。

场景:这种引擎支持从数据库中拷入/拷出CSV文件。如果从电子表格软件输出一个CSV文件,将其存放在MySQL服务器的数据目录中,服务器就能够马上读取相关的CSV文件。同样,如果写数据库到一个CSV表,外部程序也可以立刻读取它。在实现某种类型的日志记录时,CSV表作为一种数据交换格式,特别有用。

7. Federated存储引擎

该存储引擎可以不同的Mysql服务器联合起来,逻辑上组成一个完整的数据库。这种存储引擎非常适合数据库分布式应用。

Federated存储引擎可以使你在本地数据库中访问远程数据库中的数据,针对federated存储引擎表的查询会被发送到远程数据库的表上执行,本地是不存储任何数据的。

缺点:

(1).对本地虚拟表的结构修改,并不会修改远程表的结构

(2).truncate 命令,会清除远程表数据

(3.) drop命令只会删除虚拟表,并不会删除远程表

(4).不支持 alter table 命令

(5). select count(*), select * from limit M, N 等语句执行效率非常低,数据量较大时存在很严重的问题,但是按主键或索引列查询,则很快,如以下查询就非常慢(假设 id 为主索引)

select id from db.tablea where id >100 limit 10 ;

而以下查询就很快:

select id from db.tablea where id >100 and id<150

(6). 如果虚拟虚拟表中字段未建立索引,而实体表中为此字段建立了索引,此种情况下,性能也相当差。但是当给虚拟表建立索引后,性能恢复正常。

(7). 类似 where name like "str%" limit 1 的查询,即使在 name 列上创建了索引,也会导致查询过慢,是因为federated引擎会将所有满足条件的记录读取到本地,再进行 limit 处理。

场景: dblink。

8. BLACKHOLE存储引擎(黑洞引擎)

该存储引擎支持事务,而且支持mvcc的行级锁,写入这种引擎表中的任何数据都会消失,主要用于做日志记录或同步归档的中继存储,这个存储引擎除非有特别目的,否则不适合使用。

场景:如果配置一主多从的话,多个从服务器会在主服务器上分别开启自己相对应的线程,执行binlogdump命令而且多个此类进程并不是共享的。为了避免因多个从服务器同时请求同样的事件而导致主机资源耗尽,可以单独建立一个伪的从服务器或者叫分发服务器。

9. PERFORMANCE_SCHEMA存储引擎

该引擎主要用于收集数据库服务器性能参数。这种引擎提供以下功能:提供进程等待的详细信息,包括锁、互斥变量、文件信息;保存历史的事件汇总信息,为提供MySQL服务器性能做出详细的判断;对于新增和删除监控事件点都非常容易,并可以随意改变mysql服务器的监控周期,例如(CYCLE、MICROSECOND)。 MySQL用户是不能创建存储引擎为PERFORMANCE_SCHEMA的表。

场景: DBA能够较明细得了解性能降低可能是由于哪些瓶颈。

四,如何选择合适的存储引擎?

选择标准可以分为:

1. 是否需要支持事务;

2. 是否需要使用热备;

3. 崩溃恢复:能否接受崩溃;

4. 是否需要外键支持;

然后按照标准,选择对应的存储引擎即可。

存储引擎的选择:

csnd

----------------------------------------------------------------------------------------------------------------------------------------------------------------

参考资料

https://blog.csdn.net/yjclsx/article/details/81911027

https://www.cnblogs.com/andy6/p/5789248.html

https://blog.csdn.net/yjclsx/article/details/81911027

你可能感兴趣的:(Mysql中的存储引擎)