MySQL存储引擎以及MyISAM与InnoDB的区别详解
一、mysql存储引擎概述
插件式存储引擎是 mysql 最重要的特性之一,用户可以根据应用的需要选择如何存储和索引数据、是否使用事务等。mysql 默认支持多种存储引擎,以适用于不同领域的数据库应用需要,用户可以通过选择使用不同的存储引擎提高应用的效率,提供灵活的存储,用户甚至可以按照自己的需要定制和使用自己的存储引擎,以实现最大程度的可定制性。
默认情况下,创建新表不指定表的存储引擎,则新表是默认存储引擎的,如果需要修改默认的存储引擎,则可以在参数文件中设置 default-table-type。
查看当前的默认存储引擎,可以使用以下命令:
show variables like 'table_type';
查询当前数据库支持的存储引擎,有两种方法:
show engines \g show variables like"have%";
在创建新表的时候,可以通过增加 engine 关键字设置新建表的存储引擎。
create table user( id bigint(20) not null auto_increment, name varchar(20), primary key (id) ) engine=myisam default charset=gbk;
也可以使用 alter table 语句,将一个已经存在的表修改成其他的存储引擎。下面的例子介绍了如何将表 user从 myisam 存储引擎修改成 innodb 存储引擎:
alter table user engine = innodb;
二、myisam储存引擎
myisam 是 mysql 的默认存储引擎。myisam 不支持事务、也不支持外键,其优势是访问的速度快,对事务完整性没有要求或者以 select、insert 为主的应用基本上都可以使用这个引擎来创建表。
每个 myisam 在磁盘上存储成 3 个文件,其文件名都和表名相同,但扩展名分别是:
.frm(存储表定义);
.myd(mydata,存储数据);
.myi (myindex,存储索引)。
数据文件和索引文件可以放置在不同的目录,平均分布 io,获得更快的速度。
myisam 的表又支持 3 种不同的存储格式,分别是:
静态(固定长度)表;
动态表;
压缩表。
静态表是默认的存储格式。静态表中的字段都是非变长字段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。静态表的数据在存储的时候会按照列的宽度定义补足空格,但是在应用访问的时候并不会得到这些空格,这些空格在返回给应用之前已经去掉。
动态表中包含变长字段,记录不是固定长度的,这样存储的优点是占用的空间相对较少,但是频繁地更新删除记录会产生碎片,需要定期执行 optimize table 语句或 myisamchk -r 命令来改善性能,并且出现故障的时候恢复相对比较困难。
压缩表由 myisampack 工具创建,占据非常小的磁盘空间。因为每个记录是被单独压缩的,所以只有非常小的访问开支。
三、innodb存储引擎
innodb 存储引擎提供了具有提交、回滚和崩溃恢复能力的事务安全。但是对比 myisam的存储引擎,innodb 写的处理效率差一些并且会占用更多的磁盘空间以保留数据和索引。
四、memory存储引擎
memory 存储引擎使用存在内存中的内容来创建表。每个 memory 表只实际对应一个磁盘文件,格式是.frm。memory 类型的表访问非常得快,因为它的数据是放在内存中的,并且默认使用 hash 索引,但是一旦服务关闭,表中的数据就会丢失掉。
五、myisam与innodb的区别
1) 存储结构
myisam:每个myisam在磁盘上存储成三个文件。第一个文件的名字以表的名字开始,扩展名指出文件类型。.frm文件存储表定义。数据文件的扩展名为.myd (mydata)。索引文件的扩展名是.myi (myindex)。
innodb:所有的表都保存在同一个数据文件中(也可能是多个文件,或者是独立的表空间文件),innodb表的大小只受限于操作文件的大小,一般为2gb。将数据和索引存在一个文件.ibd 表结构.frm
存储区别:索引
myisam存储引擎,存储索引的b树,叶子结点上只有主键和记录的磁盘地址(非聚集索引)
主键索引(b+)主键 =====》地址====》数据
辅助索引(b+)key ======》地址====》数据
innodb存储引擎,存储索引的b+树,叶子结点存放主键和对应的数据(聚集索引)
主键索引 主键和数据
辅助索引 key 和主键
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插件支持全文索引,并且效果更好。
两个存储引擎都支持b树索引(针对磁盘索引)不支持哈希索引
memory存储引擎默认是哈希索引(memory是将数据存在内存的)
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)索引缓存(都支持)
12)外键
myisam:不支持
innodb:支持
通过上述的分析,基本上可以考虑使用innodb来替代myisam引擎了,原因是innodb自身很多良好的特点,比如事务支持、存储 过程、视图、行级锁定等等,在并发很多的情况下,相信innodb的表现肯定要比myisam强很多。另外,任何一种表都不是万能的,只用恰当的针对业务类型来选择合适的表类型,才能最大的发挥mysql的性能优势。如果不是很复杂的web应用,非关键应用,还是可以继续考虑myisam的,这个具体情况可以自己斟酌。
六、常用存储引擎对比
上一篇: 分享Python切分字符串的一个不错方法