一、InnoDB是聚集索引,Myisam是非聚集索引(或者叫辅助索引)
在磁盘中,Innodb存储的文件是frm、ibd,而Myisam是frm、MYD、MYI。
Innodb:frm是表定义文件,ibd是数据文件
Myisam:frm是表定义文件,myd是数据文件,myi是索引文件。
可以看到,Myisam比Innodb多了一个索引文件,为什么呢?因为Myisam用的是非聚集索引。
聚集索引:意思是在B+树索引中,B+树的叶子节点保存了完整的数据表的数据记录。
非聚集索引:B+树的叶子节点只存储数据记录的地址。然后还要根据数据地址去到myd数据文件中查找对应的数据记录,如下图:
如果是聚集索引就不用那么麻烦了。聚集索引的索引文件是不分开的,不像非聚集索引,它的索引文件myi和数据文件myd是分开的。
1.1 InnoDB必须要有唯一索引(如果用户没指定,系统会生成一个隐藏列Row_id来充当默认主键),Myisam则没有这个要求
叶节点包含了完整的数据记录。这种索引叫做聚集索引。因为InnoDB的数据文件本身要按主键聚集,所以InnoDB要求表必须有主键(MyISAM可以没有),如果没有显式指定,则MySQL系统会自动选择一个非空的且可以唯一标识数据记录的列作为主键,如果不存在这种列,则MySQL自动为InnoDB表生成一个隐含字段Row_id作为主键,这个字段长度为6个字节,类型为长整形。
1.2 为什么对于InnoDB而言,主键最好是自增的?
增ID可以保证每次插入时B+索引是从右边扩展的,可以避免B+树和频繁合并和分裂(对比使用UUID)。如果使用字符串主键和随机主键,会使得数据随机插入,效率比较差。
二、InnoDB支持事务,Myisam是不支持事务的 对于InnoDB每一条SQL语言都默认封装成事务,自动提交,这样会影响速度,所以最好把多条SQL语言放在begin和commit之间,组成一个事务;
三、InnoDB支持外键,Myisam不支持外键
四、InnoDB支持表锁,行锁(默认),Myisam只支持表锁
InnoDB的行锁是实现在索引上的,而不是锁在物理行记录上。潜台词是,如果访问没有命中索引,也无法使用行锁,将要退化为表锁。
如下面例子:
表锁:表级锁定,更新时,锁定机制是整张表被锁定,其它连接无法更新表的数据,效率比较低下.锁的机制成本很少,但大大降低了并发性能
五、InnoDB和Myisam使用对比
Myisam:
1.不需要事务支持的场景,读数据多的网站.
2.并发相对较低的业务,因为表级锁定的机制限制
3.数据修改相对较少的业务.阻塞问题
4.对数据要求一致性不高的业务.
5.占用资源比较少.服务器硬件不好时.可以考虑使用
其余情况可以用Innodb就用Innodb,毕竟默认是Innodb。