MySQL的存储引擎InnoDB和MyISAM
作者:??YuShiwen???? 时间:2024-01-26 02:19:30
1. MyISAM底层存储
(非聚集索引方式)与InnoDB底层存储(聚集索引方式)
1.1 MyISAM底层存储(非聚集索引方式)
Myisam 创建表后生成的文件有三个:
frm:创建表的语句
MYD:表里面的数据文件(myisam data)
MYI:表里面的索引文件(myisam index)
底层存储方式:
MyISAM 用的是非聚集索引方式,即数据和索引落在不同的两个文件上。
MyISAM 在建表时以主键作为 KEY 来建立主索引 B+树,树的叶子节点存的是对应数据的物理地址。
当我们为某个字段添加索引时,我们同样会生成对应字段的索引树,该字段的索引树的叶子节点同样是记录了对应数据的物理地址,然后也是拿着这个物理地址去数据文件里定位到具体的数据记录。
图片讲解得很清楚,大家可以结合图片看一下:
1.2 InnoDB底层存储(聚集索引方式)
Innodb 创建表后生成的文件有两个:
frm:创建表的语句
idb:表里面的数据+索引文件
底层存储方式:
InnoDB 是聚集索引方式,因此数据和索引都存储在同一个文件里。
InnoDB 在建表时以主键作为 KEY 来建立主索引 B+树,树的叶子节点存的是主键ID和主键 ID 对应的数据。
当我们为某个字段添加索引时,我们同样会生成对应字段的索引树,但是该字段的索引树的叶子节点存储的是该字段所在行的主键KEY,拿到主键 KEY 后,再去查询一下主键索引树,才可以定位到具体数据;也就是会进行两次查找。
图片讲解得很清楚,大家可以结合图片看一下:
2. InnoDB与MyISAM简介
Mysql 底层数据引擎以插件形式设计,最常见的是 Innodb 引擎和 Myisam 引擎,用户可以根据个人需求选择不同的引擎作为 Mysql 数据表的底层引擎。
MyISAM 存储引擎
是 MySQL 中常见的存储引擎,虽然性能极佳, 拥有较高的插入,查询速度,但却
不支持事务处理(transaction)
,不支持外键
。曾(MySQL 5.5及之前版本)是 MySQL 的默认存储引擎
。InnoDB 存储引擎
是MySQL的数据库引擎之一,现为MySQL的默认存储引擎,事务型数据库的首选引擎,
InnoDB
是为处理巨大数据量时的最大性能设计,支持ACID
事务,支持行级锁定。给MySQL提供了事务(transaction)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)、多版本并发控制(multi-versioned concurrency control)的事务安全(transaction-safe (ACID compliant))等功能。
ACID:
Atomicity(原子性):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
Consistency(一致性):在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
Isolation(隔离性):数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。
Durability(持久性):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
3. MyISAM与InnoDB的比较
MyISAM | InnoDB | |
---|---|---|
存储结构 | Myisam 创建表后生成的文件有三个,分别为: frm:创建表的语句 MYD:表里面的数据文件(myisam data) MYI:表里面的索引文件(myisam index) | Innodb 创建表后生成的文件有两个,分别为: frm:创建表的语句 idb:表里面的数据+索引文件 |
存储空间 | MyISAM支持支持三种不同的存储格式:静态表(默认,但是注意数据末尾不能有空格,会被去掉)、动态表、压缩表。当表在创建之后并导入数据之后,不会再进行修改操作,可以使用压缩表,极大的减少磁盘的空间占用。 | 需要更多的内存和存储,它会在主内存中建立其专用的缓冲池用于高速缓冲数据和索引。 |
可移植性、备份及恢复 | 数据是以文件的形式存储,所以在跨平台的数据转移中会很方便。在备份和恢复时可单独针对某个表进行操作; MyISAM遇到错误,必须完整扫描后才能重建索引,或修正未写入硬盘的错误; MyISAM的修复时间,与数据量的多少成正比。 | 在数据量很大的时候就相对痛苦; InnoDB可借由事务记录档(Transaction Log)来恢复程序崩溃(crash),或非预期结束所造成的数据错误; InnoDB的修复时间,大略都是固定的。 |
索引 | 非聚集索引 ,MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。 | 聚集索引 ,聚集索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。 |
事务支持 | 强调的是性能,每次查询具有原子性,其执行数度比InnoDB类型更快,但是不提供事务支持 。 | 提供事务支持 ,外部键等高级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能力(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。 |
主键自增长 | 可以和其他字段一起建立联合索引。引擎的自动增长列必须是索引,如果是组合索引,自动增长可以不是第一列,他可以根据前面几列进行排序后递增。 | InnoDB中必须包含只有该字段的索引。引擎的自动增长列必须是索引,如果是组合索引也必须是组合索引的第一列。 |
锁的粒度 | 只支持表级锁 ,用户在操作myisam表时,select,update,delete,insert语句都会给表自动加锁,如果加锁以后的表满足insert并发的情况下,可以在表的尾部插入新的数据。 | 支持行级锁 。行锁大幅度提高了多用户并发操作的性能。但是InnoDB的行锁,只是在WHERE的主键是有效的,非主键的WHERE都会锁全表的。 |
全文索引 | 支持 FULLTEXT类型的全文索引 | 不支持FULLTEXT类型的全文索引,但是innodb可以使用sphinx插件支持全文索引,并且效果更好。 |
表主键 | 允许没有任何索引和主键的表存在,索引都是保存行的地址。 | 如果没有设定主键或者非空唯一索引,就会自动生成一个6字节的主键(用户不可见),数据是主索引的一部分,附加索引保存的是主索引的值。 |
存储表的具体行数 | 保存有表的总行数,如果select count() from table;会直接取出出该值。 | 没有保存表的总行数,如果使用select count(*) from table;就会遍历整个表,消耗相当大,但是在加了wehre条件后,myisam和innodb处理的方式都一样。 |
外键 | 不支持 | 支持,对一个包含外键的 InnoDB 表转为 MYISAM 会失败。 |
4. 存储引擎的使用
什么时候用MyISAM数据存储引擎?什么时候用InnoDB数据存储引擎?
《高性能MySQL》中写道:
InnoDB:MySQL默认的事务型引擎,也是最重要和使用最广泛的存储引擎。它被设计成为大量的短期事务,短期事务大部分情况下是正常提交的,很少被回滚。InnoDB的性能与自动崩溃恢复的特性,使得它在非事务存储需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。
MyISAM:在MySQL 5.1 及之前的版本,MyISAM是默认引擎。MyISAM提供的大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM并不支持事务以及行级锁,而且一个毫无疑问的缺陷是崩溃后无法安全恢复。正是由于MyISAM引擎的缘故,即使MySQL支持事务已经很长时间了,在很多人的概念中MySQL还是非事务型数据库。尽管这样,它并不是一无是处的。对于只读的数据,或者表比较小,可以忍受修复操作,则依然可以使用MyISAM(但请不要默认使用MyISAM,而是应该默认使用InnoDB)。
总结:
MyISAM管理非事务表,提供高速存储和检索以及全文搜索能力,如果再应用中执行大量select操作,应该选择MyISAM
InnoDB用于事务处理,具有ACID事务支持等特性,如果在应用中执行大量insert和update操作,应该选择InnoDB
来源:https://juejin.cn/post/7084093849198395399