InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定。基本 的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快。InnoDB 是 MySQL 上第一个提供外键约束的引擎,除了提供事务处理外,InnoDB 还支持行锁。
mysql索引的存储类型目前只有两种(btree和hash),具体和存储引擎模式相关:
MyISAM btree
InnoDB btree
MEMORY/Heap hash,btree
弊端:hash 索引在任何时候都不能避免表扫描(hash表扫描)。 前面已经知道,hash 索引是将索引键通过 hash 运算之后,将 hash运算结果和所对应的行指针信息存放于一个 hash 表中,由于不同索引键可能存在相同 hash 值,所以即使取满足某个 hash 键值的数据的记录条数,也无法从 hash 索引中直接完成查询,还是要通过访问表中的实际数据进行相应的比较,并得到相应的结果。
InnoDB注意事项:
1、InnoDB在5.6之前不支持全文索引,但是之后的版本支持全文索引
2、InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。
3、对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。
4、DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。
5、LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。
6、InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update
table set num=1 where name like “%aaa%”(通过这个理解全表扫描的情况)
7,InnoDB肯定有聚簇索引,MyISAM不支持聚簇索引,当InnoDB引擎的表中指定主键则这个主键为BTree聚簇索引,如果没有指定则使得第一个唯一索引且非null为聚簇索引,否则自动生成一个字段并作为聚簇索引,这些都是强制进行的(可能有其他方式使得这个功能取消)。
8,在InnoDB中非聚簇索引中的索引存储的是聚簇索引的主键值而不是具体的行的地址,(这里要注意这个原因:InnoDB肯定有聚簇索引,而聚簇索引必然用到BTree,BTree聚簇索引有一个特点就是叶结点存放的就是数据实体本身,而不是数据实体的地址引用,因此在索引到具体的数据的时候索引与数据实体往往在同一个页上,这有效减少了磁盘IO的次数,因此效率相对来说很高)而MyISAM引擎存放的是具体行的地址(MyISAM不支持聚簇索引,因此数据实体的存放比较分散,虽然相对于InnoDB在内存级别取数据比较快,但是数据的分散导致磁盘IO次数增加,而磁盘IO与内存的IO效率差距很大,总体上InnoDB就比MyISAM效率高)
MyISAM注意事项:
1、支持全文索引
2,不支持事务,外键
3,不支持聚簇索引
4,保存数据行数
5,最小提供表锁
很多以前的教科书上都是写的MyISAM是mysql的默认存储引擎,其实自从mysql5.5开始,默认存储引擎就已经改变成为InnoDB了
MyISAM不支持事务和外键,正式由于这个其性能较佳,尤其在读数据。
MyISAM在加锁的时候会对整张表都加锁(但是这里要明白共享锁和独占锁在实际使用中的区别),这也是MyISAM广为诟病的一点,但是在处理并发上,在读取数据的时候,所有的表上都可以获得共享锁,也就是每个连接会互不干扰,而在写数据的时候,会获得排他锁,会对整个表进行加锁,其他的请求包括读和写都必须处于等待状态。