MySQL存储引擎

MySQL 可以将数据以不同的技术存储在文件(内存)中,这种技术就称之为存储引擎(也叫表类型),每一种存储引擎使用不同的存储机制,索引技巧,锁定水平,最终提供广泛且不同的功能。 MySQL中存储引擎负责数据的存储和提取

MySQL并不完美,但是却很灵活,灵活性最重要的体现在存储引擎
MySQL的核心,最与众不同的特性就是存储引擎架构这种架构设计将查询处理及其他的系统任务 和 数据的存储/提取相分离,这种设计可以在使用时根据性能,特性以及其他需求来选择数据存储的方式。

MySQL 服务器的架构:
第一层(最上层):主要处理连接处理,授权认证,安全等 ,(身份认证,权限认证
第二层: 大多数mysql核心服务功能都在这一层,包括解析查询,分析优化,缓存,以及所有的内置函数,另外所有跨存储引擎的功能都是在这一层实现的:存储过程,触发器,视图等
第三层: 包含了存储引擎,负责数据的存储和提取,服务器通过API和存储引擎通信,这些接口屏蔽了不同存储引擎之间的差别,存储引擎有几十个底层函数,用于执行开始一个事务,或者提取某一行数据等操作,不会解析SQL,不同的存储引擎之间也不会通信。

优化与执行
1、MySQL会解释查询,并创建内部数据结构(解析树),然后对其进行各种优化,包括重写查询、决定表的读取顺序,以及选择合适的索引等。

2、 对于SELECT语句,在解析查询之前,服务器会先检查查询缓存,如果能命中,服务器就不必再执行查询解析、优化和执行的整个过程,直接返回查询缓存中的结果集。

MySQL 提供的几种存储引擎,经常使用的主要是前3种
MyISAM : 5.0以前的默认存储引擎,不支持事务,会将表存储在两个文件之中,数据文件和索引文件,分别以.MYD和.MYI为扩展名,锁的粒度为表级锁,不支持崩溃安全修复,不支持外键,但是可以支持全文索引和数据压缩(是innodb不具备的),而且还可以支持延迟更新索引建(即每次修改之后,先将内存中的键缓冲区修改,然后再将索引数据写入磁盘)
InnoDB mySql 默认的存储引擎,支持事务,支持外键,数据存储在一个表中,不区分动态行和静态行(固定长度大小的行称为静态行,所以InnoDb中建议适应varchar),采用MVCC来支持高并发,表是基于聚簇索引建立的(主键一定是聚簇索引,而聚簇索引不一定为主键),存储格式是平台独立的,支持真正的热备份(数据库在运行的状态下备份数据)。InnoDB不支持全文索引,但是可以使用sphinx插件来实现
MyISAM相对比InnoDB来说需要占用的内存空间少,适合于不需要事务,而且主要是查询和插入的操作,否则建议使用InnoDB存储引擎

Memory 最大的特点是数据全部存放在内存中,不需要进行磁盘的I/O操纵,因此速度是非常快的,适合于查找或者保存数据分析中的中间数据,但是Memory表一旦重启或者崩溃之后,数据会全部丢失,所以慎用(其实mySQL中执行查询过程中内部用来保存中间结果的临时表就是Memory表,但是临时表也可以用其他存储引擎来表示,只在单个连接中可见,一旦连接断开,临时表也就消失了
CSV
Archive
另外还有一些第三方的存储引擎,
第一类:OLTP类引擎,比如XtraDB(完全是InnoDB的改进版本,可以兼容InnoDB) ToKuDB(使用了一种叫分形树的存储索引结构,该结构与缓存无关,是一种大数据的存储引擎,拥有很高的压缩比,可以在很大的数据量上创建索引)
第二类: 面向列的存储引擎,一般来说存储引擎都是面向行的,但是在大数据量的处理时,面向列的方式能传输更少的数据,更高效,而且面向列单独存储的话,压缩的效率也会非常的高。比如 Infobright (为数据分析和数据仓库设计(数十TB),数据高度压缩,按照块进行排序,不支持索引,索引在如此大的数据量也很难管用,块结构也是一种准索引),InfiniDB
这里写图片描述
设置存储引擎命令:
create Table user(
……….
)engine = MyISAM;
Alter table user engine = InnoDB;

MyISAM与InnoDB的区别是什么?

1、 存储结构

MyISAM:每个MyISAM在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.MYD (MYData)。索引文件的扩展名是.MYI (MYIndex)。
InnoDB:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),InnoDB表的大小只受限于操作系统文件的大小,一般为2GB。

2、 存储空间

MyISAM:可被压缩,存储空间较小。支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。
InnoDB:需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。

3、 可移植性、备份及恢复

MyISAM:数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作。
InnoDB:免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump,在数据量达到几十G的时候就相对痛苦了。

4、 事务支持

MyISAM:强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持。
InnoDB:提供事务支持事务,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。

5、 AUTO_INCREMENT

MyISAM:可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。
InnoDB:InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。

6、 表锁差异

MyISAM:只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。
InnoDB:支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。

7、 全文索引

MyISAM:支持 FULLTEXT类型的全文索引
InnoDB:不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。

8、 表主键

MyISAM:允许没有任何索引和主键的表存在,索引都是保存行的地址。
InnoDB:如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。

9、 表的具体行数

MyISAM:保存有表的总行数,如果select count(*) from table;会直接取出出该值。
InnoDB:没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。

10、 CURD操作

MyISAM:如果执行大量的SELECT,MyISAM是更好的选择。
InnoDB:如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表。DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。

11、 外键

MyISAM:不支持
InnoDB:支持
通过上述的分析,基本上可以考虑使用InnoDB来替代MyISAM引擎了,原因是InnoDB自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥MySQL的性能优势。如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。

InnoDB 中的事务 和 事务日志
MySQL 中的事务的提交默认是自动提交的 AUTOCOMMIT , 也就是说如果没有显式的开始一个事务(begin …SQL语句….. commit ),则每一次查询都被认为是一个事务执行提交操作。
MySQL 可以通过执行 SET TRANACTION IOSLATIONLEAVEL 隔离级别, 来设置隔离级别,在设置后的下一个事务生效,也可以通过配置文件中设置隔离级别。
MySQL的事务是由存储引擎实现的,因此一个事务中使用多种存储引擎是不可靠的。
InnoDB 使用的是两段锁协议,锁只有在commit或者rollback的时候才会释放,而且所有锁是在同一时刻释放, InnoDB 会根据隔离级别在需要的时候自动加锁
InnoDB 是行级锁,设置了事务的隔离级别会自动的加锁,所以不建议显示使用 lock table 等语句,没有用处,而且还会影响性能

事务日志可以帮助提高事务的效率,使用事务日志的时候,修改数据库中的数据分为三步:(修改数据需要2次写磁盘的操作,称为预写式日志,大多数存储引擎都是这样实现数据修改的)
第一步:InnoDB存储引擎在修改表的数据的时候,先需要修改内存中的数据
第二步:然后将修改操作记录持久到硬盘中的事务日志中
第三步:之后内存中被修改的数据通过事务日志在后台慢慢的刷回到磁盘中的数据文件中
这样避免了每次修改数据,都要把数据刷回到磁盘中,节省了I/O的开销。而且事务日志是通过追加的方式添加的,因此写日志的时候,磁头不需要来回的移动来查找要写的事务日志的位置,所以采用事务日志的方式要快的多。
如果数据的修改已经写入到日志中了,但是还没有修改到数据库中,此时系统崩溃,存储引擎在重启的时候会自动的恢复这部分修改的数据。

事务日志一般又 redo 和undo 两种,
undo : 记录更改前的一份copy,记录前印象, 用于回滚,事务还未递交,由于内有限,数据库系统会将脏块写入到数据文件中,以便腾出宝贵的内存供其它进程使用,因此就需要undo记录来用于事务失败将数据回滚到之间的值。
redo ; 记录所有的对数据库的操作,用于恢复数据,事务已经递交, 每次commit时,将数据的修改立刻写入redo中,但是还未写入数据文件,此时系统崩溃,在恢复时需要将数据从日志文件中找出来,重新应用一下,使已经更改数据在数据文件中也改过来。
两者的关系:只有先redo 成功了,才能保证undo 里面的东西都是正确的,然后才能rollback,不做undo,系统就不会知道之前的状态,redo就无从谈起

部分内容引用自:
http://blog.csdn.net/erjian666/article/details/53043618

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值