自己整理的一个表格
区别 | MyISAM | InnoDB |
存储结构 | 每个MyISAM在磁盘上存储成三个文件 .frm文件存储表定义 MYD(MYData,存储数据文件) MYI(MTIndex,存储索引文件) | 所有的表都保存在同一个数据文件中(若独立表空间开启则是多个文件) InnoDB表的大小只受限于系统文件的大小,一般是2GB |
存储空间 | 可被压缩,存储空间较小,支持三种不同的存储格式 静态表(默认,但数据末尾不能有空格,会被去掉) 动态表 压缩表 | 需要更多的内存和存储,他会在主内存中建立专用的缓冲池用于高速缓冲数据和索引 |
事物支持 | 强调是的性能,执行速度比InnoDB类型更快,但是不支持事物 | 支持事物,外部键等数据库功能,具有事物(commit)回滚(rollback)和崩溃修复能力的事物安全(ACID)型表 |
自增长 | 可以和其他字段以前建立联合索引,自动增长列必须是索引 | 必须包含只有该字段的索引,自动增长列必须是索引,若是组合索引也必须是组合索引的第一列 |
表锁差异 | 只支持表级锁,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据 | 支持事务和行级锁,是innodb的最大特色。行锁大幅度提高了多用户并发操作的新能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的 |
表主键 | 允许没有任何索引和主键的表存在,索引都是保存行的地址 | 如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值 |
表的具体行数 | 保存有表的总行数,如果select count(*) from table;会直接取出出该值 | 没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样 |
增删改查 | 如果执行大量的SELECT,MyISAM是更好的选择 | 如果执行大量的INSERT或UPDATE,应该使用InnoDB表。 DELETE 从性能上InnoDB更优,但DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除,在innodb上如果要清空保存有大量数据的表,最好使用truncate table这个命令。 |
外键 | 不支持 | 支持 |
INNODB在做SELECT的时候,要维护的东西比MYISAM引擎多很多:
1)数据块,INNODB要缓存,MYISAM只缓存索引块, 这中间还有换进换出的减少;
2)innodb寻址要映射到块,再到行,MYISAM记录的直接是文件的OFFSET,定位比INNODB要快
3)INNODB还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护
1)数据块,INNODB要缓存,MYISAM只缓存索引块, 这中间还有换进换出的减少;
2)innodb寻址要映射到块,再到行,MYISAM记录的直接是文件的OFFSET,定位比INNODB要快
3)INNODB还需要维护MVCC一致;虽然你的场景没有,但他还是需要去检查和维护
MVCC (Multi-Version Concurrency Control)多版本并发控制
注释:
注释:
InnoDB:通过为每一行记录添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。但是InnoDB并不存储这些事件发生时的实际时间,相反它只存储这些事件发生时的系统版本号。这是一个随着事务的创建而不断增长的数字。每个事务在事务开始时会记录它自己的系统版本号。每个查询必须去检查每行数据的版本号与事务的版本号是否相同。让我们来看看当隔离级别是REPEATABLEREAD时这种策略是如何应用到特定的操作的:
SELECT InnoDB必须每行数据来保证它符合两个条件:
1、InnoDB必须找到一个行的版本,它至少要和事务的版本一样老(也即它的版本号不大于事务的版本号)。这保证了不管是事务开始之前,或者事务创建时,或者修改了这行数据的时候,这行数据是存在的。
2、这行数据的删除版本必须是未定义的或者比事务版本要大。这可以保证在事务开始之前这行数据没有被删除