Mysql中MyISAM和InnoDB的区别及说明

 更新时间:2022年12月26日 11:12:53   作者:杨 戬  
这篇文章主要介绍了Mysql中MyISAM和InnoDB的区别及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

MyISAM和InnoDB的区别

1. 定义

InnoDB:

InnoDB:MySQL默认的事务型引擎,也是最重要和使用最广泛的存储引擎。

它被设计成为大量的短期事务,短期事务大部分情况下是正常提交的,很少被回滚。InnoDB的性能与自动崩溃恢复的特性,使得它在非事务存储需求中也很流行。除非有非常特别的原因需要使用其他的存储引擎,否则应该优先考虑InnoDB引擎。

MyISAM:

MyISAM:在MySQL 5.5 及之前的版本,MyISAM是默认引擎。

MyISAM提供的大量的特性,包括全文索引、压缩、空间函数(GIS)等,但MyISAM并不支持事务以及行级锁,而且一个毫无疑问的缺陷是崩溃后无法安全恢复。正是由于MyISAM引擎的缘故,即使MySQL支持事务已经很长时间了,在很多人的概念中MySQL还是非事务型数据库。尽管这样,它并不是一无是处的。对于只读的数据,或者表比较小,可以忍受修复操作,则依然可以使用MyISAM(但请不要默认使用MyISAM,而是应该默认使用InnoDB)

2. 区别

InnoDB 支持事务,MyISAM 不支持事务。这是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

InnoDB 支持外键,而 MyISAM 不支持。对一个包含外键的 InnoDB 表转为 MYISAM 会失败;

InnoDB 是聚集索引,MyISAM 是非聚集索引。聚簇索引的文件存放在主键索引的叶子节点上,因此 InnoDB 必须要有主键,通过主键索引效率很高。但是辅助索引需要两次查询,先查询到主键,然后再通过主键查询到数据。因此,主键不应该过大,因为主键太大,其他索引也都会很大。而 MyISAM 是非聚集索引,数据文件是分离的,索引保存的是数据文件的指针。主键索引和辅助索引是独立的。

InnoDB 不保存表的具体行数,执行 select count(*) from table 时需要全表扫描。而MyISAM 用一个变量保存了整个表的行数,执行上述语句时只需要读出该变量即可,速度很快;

InnoDB 最小的锁粒度是行锁,MyISAM 最小的锁粒度是表锁。一个更新语句会锁住整张表,导致其他查询和更新都会被阻塞,因此并发访问受限。

这也是 MySQL 将默认存储引擎从 MyISAM 变成 InnoDB 的重要原因之一;

3. 使用

是否要支持事务,如果要请选择 InnoDB,如果不需要可以考虑 MyISAM;

如果表中绝大多数都只是读查询,可以考虑 MyISAM,如果既有读写也挺频繁,请使用InnoDB。

系统奔溃后,MyISAM恢复起来更困难,能否接受,不能接受就选 InnoDB;

MySQL5.5版本开始Innodb已经成为Mysql的默认引擎(之前是MyISAM),说明其优势是有目共睹的。如果你不知道用什么存储引擎,那就用InnoDB,至少不会差。

MyISAM和InnoDB索引结构分析

存储引擎作用于什么对象

存储引擎是作用在表上的,而不是数据库。

MyISAM和InnoDB对索引和数据的存储在磁盘上是如何体现的

先来看下面创建的两张表信息,role表使用的存储引擎是MyISAM,而user使用的是InnoDB:

再来看下两张表在磁盘中的索引文件和数据文件:

1. role表有三个文件,对应如下:

  • role.frm:表结构文件
  • role.MYD:数据文件(MyISAM Data)
  • role.MYI:索引文件(MyISAM Index)

2. user表有两个文件,对应如下:

  • user.frm:表结构文件
  • user.ibd:索引和数据文件(InnoDB Data)

也由于两种引擎对索引和数据的存储方式的不同,我们也称MyISAM的索引为非聚集索引,InnoDB的索引为聚集索引

MyISAM主键索引与辅助索引的结构

我们先列举一部分数据出来分析,如下:

上面已经说明了MyISAM引擎的索引文件和数据文件是分离的,我们接着看一下下面两种索引结构异同。

1. 主键索引:

上一篇文章已经介绍过数据库索引是采用B+Tree存储,并且只在叶子节点存储数据,在MyISAM引擎中叶子结点存储的数据其实是索引和数据的文件指针两类。

如下图中我们以Col1列作为主键建立索引,对应的叶子结点储存形式可以看一下表格。

通过索引查找数据的流程:先从索引文件中查找到索引节点,从中拿到数据的文件指针,再到数据文件中通过文件指针定位了具体的数据。

2. 辅助(非主键)索引:

以Col2列建立索引,得到的辅助索引结构跟上面的主键索引的结构是相同的。

 

InnoDB主键索引与辅助索引的结构

1. 主键索引:

我们已经知道InnoDB索引是聚集索引,它的索引和数据是存入同一个.idb文件中的,因此它的索引结构是在同一个树节点中同时存放索引和数据,如下图中最底层的叶子节点有三行数据,对应于数据表中的Col1、Col2、Col3数据项。

2. 辅助(非主键)索引:

这次我们以数据表中的Col3列的字符串数据建立辅助索引,它的索引结构跟主键索引的结构有很大差别,我们来看下面的图:

在最底层的叶子结点有两行数据,第一行的字符串是辅助索引,按照ASCII码进行排序,第二行的整数是主键的值。

InnoDB索引结构需要注意的点

  • 1. 数据文件本身就是索引文件
  • 2. 表数据文件本身就是按B+Tree组织的一个索引结构文件
  • 3. 聚集索引中叶节点包含了完整的数据记录
  • 4. InnoDB表必须要有主键,并且推荐使用整型自增主键

正如我们上面介绍InnoDB存储结构,索引与数据是共同存储的,不管是主键索引还是辅助索引,在查找时都是通过先查找到索引节点才能拿到相对应的数据,如果我们在设计表结构时没有显式指定索引列的话,MySQL会从表中选择数据不重复的列建立索引,如果没有符合的列,则MySQL自动为InnoDB表生成一个隐含字段作为主键,并且这个字段长度为6个字节,类型为整型。

那为什么推荐使用整型自增主键而不是选择UUID?

UUID是字符串,比整型消耗更多的存储空间;

在B+树中进行查找时需要跟经过的节点值比较大小,整型数据的比较运算比字符串更快速;

自增的整型索引在磁盘中会连续存储,在读取一页数据时也是连续;UUID是随机产生的,读取的上下两行数据存储是分散的,不适合执行where id > 5 && id < 20的条件查询语句。

在插入或删除数据时,整型自增主键会在叶子结点的末尾建立新的叶子节点,不会破坏左侧子树的结构;UUID主键很容易出现这样的情况,B+树为了维持自身的特性,有可能会进行结构的重构,消耗更多的时间。

为什么非主键索引结构叶子节点存储的是主键值?

保证数据一致性和节省存储空间,可以这么理解:商城系统订单表会存储一个用户ID作为关联外键,而不推荐存储完整的用户信息,因为当我们用户表中的信息(真实名称、手机号、收货地址···)修改后,不需要再次维护订单表的用户数据,同时也节省了存储空间。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mysql 动态生成测试数据

    mysql 动态生成测试数据

    mysql 动态生成测试数据的语句,方便测试数据。
    2009-08-08
  • mysql千万级数据分页查询性能优化

    mysql千万级数据分页查询性能优化

    本文给大家分享的是作者在使用mysql进行千万级数据量分页查询的时候进行性能优化的方法,非常不错的一篇文章,对我们学习mysql性能优化非常有帮助
    2017-11-11
  • 解决Navicat Premium 连接 MySQL 8.0 报错

    解决Navicat Premium 连接 MySQL 8.0 报错"1251"的问题分析

    这篇文章主要介绍了解决Navicat Premium 连接 MySQL 8.0 报错"1251"的问题分析,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • MySQL on k8s 云原生环境部署

    MySQL on k8s 云原生环境部署

    这篇文章主要为大家介绍了MySQL on k8s 云原生环境部署实现过程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • MySQL问答系列之如何避免ibdata1文件大小暴涨

    MySQL问答系列之如何避免ibdata1文件大小暴涨

    MySql innodb如果是共享表空间,ibdata1文件会越来越大,所以下面这篇文章主要给大家介绍了关于MySQL问答系列之如何避免ibdata1文件大小暴涨的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2018-09-09
  • 一文带你了解MySQL的左连接与右连接

    一文带你了解MySQL的左连接与右连接

    在MySQL中,左查询和右查询是通过使用LEFT JOIN和RIGHT JOIN关键字来执行的,本文通过详细的代码示例简单介绍这两种查询方法的语法,需要的朋友可以参考下
    2023-07-07
  • mysql一次将多条不同sql查询结果并封装到一个结果集的实现方法

    mysql一次将多条不同sql查询结果并封装到一个结果集的实现方法

    这篇文章主要给大家介绍了关于mysql一次将多条不同sql查询结果并封装到一个结果集的实现方法,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2023-03-03
  • 删除MySQL数据库的简单教程

    删除MySQL数据库的简单教程

    这篇文章主要介绍了删除MySQL数据库的简单教程,是MySQL入门学习中的基础知识,需要的朋友可以参考下
    2015-05-05
  • MySQL按照汉字的拼音排序简单实例

    MySQL按照汉字的拼音排序简单实例

    下面小编就为大家带来一篇MySQL按照汉字的拼音排序简单实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-01-01
  • 深入浅析MySQL Explain

    深入浅析MySQL Explain

    这篇文章主要介绍了MySQL Explain详解,expain出来的信息有10列,分别是id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,本文对每一字段进行逐一解释,需要的朋友可以参考下
    2022-07-07

最新评论