MyIsam不支持事务和外键,访问速度更快。每个MyIsam在磁盘上存储为3个文件: .frm(存储表的定义);MYD(myData,存储数据);MYI(MYIndex,存储索引)。数据文件和索引文件可以放在不同的目录,平均分配IO,获取更快的速度,需要在创建表的时候来进行制定绝对路径。
InnoDB是MySQL默认、最常用的存储引擎,目前在很多的互联网公司使用,是一个健壮的事务性存储引擎。InnoDB还引入了行级锁定和外键约束(阿里规约不推荐使用)。支持单机事务、分布式事务、高并发的读写。
数据库的索引分为主键索引(Primary Inkex)与普通索引(Secondary Index),MyIsam和InnoDB都是采用MySql的B+树索引。他俩的主要差异在于:
一)MyIsam的索引和行记录是分开的,叫做非聚集索引(UnClustered Index),其主键索引和普通索引没有本质差异,其中MyIsam的表可以没有主键。
有连续聚集的区域单独存储行记录。主键索引的节点存储的是主键与其对应的行记录的指针普通索引的叶子节点,存储索引列预计对应的记录的指针主键索引和普通索引是两颗独立的索引B+树,基本上没有区别。二)InnoDB的索引
InnoDB的主键索引与行记录是存储在一起的,所以叫做聚集索引(Clustered Index),所以InnnoDB表必须有主键,如果没有定义PK,则第一个非空唯一索引为主键,如果都没有,则会自动创建一个隐藏的row_id作为主键。
没有单独的区域存储记录(与MyIsam的差异)主键索引的叶子节点直接对应记录,所以通过PK查询是非常的快的。普通的索引,叶子节点存储的是主键(所以不建议主键的长度过大,会导致普通索引过于庞大,如UUID等,建议直接使用自增的ID来作为主键)。通过普通索引查询其实是进行了两次2叉数的遍历:先通过索引查询,然后通过聚集索引定位到记录一)MyIsam的锁
myISAM表的读操作,不会阻塞其他用户对同一个表的读请求,但会阻塞对同一个表的写请求。myISAM表的写操作,会阻塞其他用户对同一个表的读和写操作。 myISAM表的读、写操作之间、以及写操作之间是串行的。所以MyIsam如果写入比较多的话,性能损耗会比较多二)InnoDB的锁
InnoDB与MyISAM最大不同有两点:
支持事务采用行级锁InnoDB存储引擎既支持行级锁,也支持表级锁,默认情况下采用行级锁。”,innoDB甚至采用的是pages锁,介于行锁和页锁之间。这个在下一个篇幅主要去学习。
核心要点:Mysql行锁是针对索引加的锁,不是针对记录加的锁,索引虽然访问不同的记录,但是他们的索引相同,是会出现冲突的
MyISAM:执行读写SQL语句时,会对表加锁,所以数据量大,并发量高时,性能会急剧下降。对于大量少量写入的还算是合适,通过可以使用MERGE_MyISAM来实现自动分表,但是大部分互联网公司已经不再使用MyISAM。
InnoDB:细粒度行锁,在数据量大,并发量高时,性能比较优异。
InnoDB的行锁是实现在索引上的,而不是所在物理行记录上。如果访问没有命中索引,也无法使用行锁,将退化为表锁。所以InnoDB务必建好索引,否则锁粒度较大,会影响并发。举个栗子:
t_user(uid, uname, age, sex) innodb;
uid PK 无其他索引update t_user set age=10 where uid=1;
命中索引,行锁。
update t_user set age=10 where uid!=1;
未命中索引,表锁。
update t_user set age=10 where name = "xxx";
没有索引,表锁。
参考资料: https://mp.weixin.qq.com/s/R3yuitWpHHGWxsUcE0qIRQ InnoDB并发如此高,原因竟然在这
https://mp.weixin.qq.com/s/FUXPXKfKyjxAvMUFHZm9UQ 了解MyISAM与InnoDB的索引差异
https://blog.csdn.net/hsd2012/article/details/51112009 MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详解
https://m.toutiaocdn.com/group/6711672885959721479/?app=news_article_lite×tamp=1562894384&req_id=20190712091943010024098008909B597&group_id=6711672885959721479 mysql索引介绍。
