Mysql 的Innodb引擎和Myisam数据结构和区别

先大体看一下MySQL的SQL layer层的一个架构流程:

Mysql 的Innodb引擎和Myisam数据结构和区别

简要介绍一些关键模块:

[En]

Give a brief description of some key modules:

  1. 初始模块:初始一些参数,比如初始myinit配置文件(在安装的根目录下)里的一些参数。

  2. 连接管理模块:启动监听,监听连接请求

  3. 连接进程模块:可以理解为线程池

  4. 用户模块:检验用户,令牌和权限

  5. 命令分发器:处理不同类型的请求

  6. 查询缓存模块:做缓存处理,做查询的cache,可以理解为一个Map,查询语句为key,结果值为value

  7. 日志记录模块

  8. 命令解析器(parser):对于不同类型的sql语句进行处理分发,select:查询优化器,dml:表变更模块,ddl:表维护模块,rep:复制模块(主从复制),status:状态模块。

  9. 访问控制:

  10. 表管理模块:

  11. 存储引擎接口:和Storage Engines打交道

直接来到Storage Engines,这讲的最多的就是引擎了,如:

Myisam、Innodb、Faicon、Memory、Archive等等引擎

而我们常用的是Innodb和Myisam这两种,这两种索引最直接的区别,可以从采用对应引擎而生成的数据表文件,进行对比。比如:采用Innodb引擎生成表A,采用Myisam索引生成表B。

现在可以从Mysql安装目录/data/数据库名 ,这个目录下看到有5个文件:

A.frm : 表定义文件

A.ibd :数据和索引都存储在这个文件

B.frm :表定义文件

B.myd :数据文件

B.myi :索引文件

显然,两者从文件上体验出来的区别就是,Myisam是把数据和索引分开存储在两个不同的文件里。(那其本质里的区别是什么?急啥)

让我们来看看,衡量一个指数的标准是什么?

[En]

Let’s see, what are the criteria for measuring an index?

就是,IO渐进复杂度,翻译成人话就是:当数据越来越多的时候,索引是否依然高效,即查询依然那么快。

索引的效率在一定程度上取决于它使用的索引结构。

[En]

The efficiency of an index depends to some extent on the index structure it uses.

Hash索引:

对索引字段做Hash计算,落到不同槽里面,有个明显的缺点是,无法做范围查询,例如 select * from data where id >1

Fulltext索引:

全文搜索索引,比如字段的值是:abcdefghijk,它就会再生成一列abcde* ,用于前缀的模糊全文搜索。

R-Tree索引:

引用的场景主要是 空间索引,比如说,美团上订电影票,就可以选择3km范围内的影院,结果就搜出来了。

B-Tree索引:

这个索引就是我要重点讲的索引,因为Innodb和Myisam采用的是B+ Tree 索引,而B+ Tree是从B-Tree基础上演变而来。

那B-Tree是怎么样的呢?如图:

Mysql 的Innodb引擎和Myisam数据结构和区别

每个节点上有一个索引(上方的数字,id的值),和索引对应的数据(下方蓝色:id, name)

而B+Tree:

Mysql 的Innodb引擎和Myisam数据结构和区别

上方白色的数字都为索引的key,而data全放在下面。(居于此结构,如果想知道它是怎么根据key从上到下找到对应的data的,我提供一个非常好玩的web工具,去玩一下琢磨一下。https://www.cs.usfca.edu/~galles/visualization/Algorithms.html)

虽然Innodb和Myisam都是采用B+Tree索引,但是它们是有区别的,如图:

Mysql 的Innodb引擎和Myisam数据结构和区别

Mysql 的Innodb引擎和Myisam数据结构和区别

前面已经说了,Myisam引擎方式的,会把索引和数据分开存储在两个文件中,一个文件负责数据的插入、更新等,另一个负责索引的维护。如图,索引中白色的key为索引的值,下面浅绿色为data:对应数据的地址。如果多个索引就,就多个这种模式,如图,以name为索引,也是一样。

而Innodb:如图:

Mysql 的Innodb引擎和Myisam数据结构和区别

Mysql 的Innodb引擎和Myisam数据结构和区别

上面也提到,Innodb是把数据和索引都放在同一个文件里的,那索引和数据共存的形式是:如图,白色中的为key,即使索引,当从上到下找到对应的key之后,key下面存放的就是整条对应的数据了,而不是想Myisam那样存放的是数据对应的地址了。

那么问题来了,Innodb多个索引的话,是一种什么样的存在呢,还是如上图右方,增加字段name为索引:它就会建立一个副索引树,同样的结构,白色key索引存放的是name字段对应的值,而蓝色方的data存放的是主索引树的key。

举个例子,当id和name都作为索引的时候,执行select * from table where name = ‘james’ ,

第一步会先在副索引找到key为james的data为1,1是主索引的key。

第二步再到主索引找到key为对1的数据。(select * from table where id= 1)

多提一句,像这种索引的方式叫”聚集索引”,理解为key和data都绑定在一起了。

而Myisam的那种索引的方式叫做”非聚集索引”。

对于B+Tree这种索引,讨论一下uuid和自增id。

Uuid是32位的,毋庸置疑,相对于自增id,uuid的存储空间是较大的。而且uuid为索引时,其要进行较复杂的运算,最终确定索引的key要插入到哪个位置。

而自增id,它符合每次加1的规则,而且规矩已经确定了,它不要做过多的运算,直接从左到右进行横向的扩展(插入),这样性能就有了差别,如图(B+Tree树的高度是固定的,为4层):

Mysql 的Innodb引擎和Myisam数据结构和区别

Mysql 的Innodb引擎和Myisam数据结构和区别

即使是这样,uuid依然在一些项目依然有它市场:

自增id虽然有多个优点,但实际大型项目中却很少采用自增长id的,这是为什么呢?因为uuid几乎保证了不同数据库的不同表的id唯一,可以进行数据切分合并,而自增长id只能保证一个数据库中的一张表的id唯一,进行数据库合并的话并然会因主键冲突而失败,这是一个硬伤。

而且有博主说:分布式架构,意味着需要多个实例中保持一个表的主键的唯一性。这个时候普通的单表自增ID主键就不太合适,因为多个mysql实例上会遇到主键全局唯一性问题

让我们来谈谈组合指数的几个小问题。

[En]

Let’s talk about some minor problems of combinatorial index.

组合指数是有序的,称为最左原理。你什么意思。例如:

[En]

The combinatorial index is ordered, called the leftmost principle. What do you mean. For example:

name、age、weight 这3个字段组成组合索引,name排在第1位,那么查询语句where 后面必须要有name=”value”这个条件,否则此索引是不起作用的,这叫最左原则。

再引用网上的一个例子:

Mysql 的Innodb引擎和Myisam数据结构和区别

索引的好处就是:

  1. 提高检索效率

  2. 降低排序成本,索引对应的字段是会有一个自动排序功能的,默认是升序asc。

Every coin has two sides,它缺点是

  1. 更新索引的IO量。

也就是说,当插入一条数据时,除了插入数据本身之外,还需要插入该数据对应的索引信息的节点,如果对应的表是多个索引,则插入多个数据对应的索引信息节点。并且这些文件作为文件类型存储在硬盘上。

[En]

That is to say, when inserting a piece of data, in addition to inserting the data itself, it is also necessary to insert the node of the index information corresponding to the data, and if the corresponding table is of multiple indexes, the index information node corresponding to multiple data is inserted. And these are stored on the hard disk as file types.

  1. 调整索引所致的计算量,

这个又是怎么理解呢,举个例子,像B-tree索引,在插入索引之前,都要进行计算,该索引要申请多少的空间,插入到哪个位置。

  1. 占用存储空间。

指数可以是好的也可以是坏的。你什么时候需要,什么时候不需要?

[En]

The index can be bad or good. When do you need it and when you don’t?

适合:

  1. 较频繁的作为查询条件的字段应该创建索引

不适合:

  1. 字段值的唯一性太差不适合单独做索引

  2. 更新非常频繁的字段不是

  3. 不会出现在where句中的字段不适合。

Mysql 的Innodb引擎和Myisam数据结构和区别

Original: https://www.cnblogs.com/incognitor/p/16403979.html
Author: 無名之徒
Title: Mysql 的Innodb引擎和Myisam数据结构和区别

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505276/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • MySQL-过滤数据(WHERE语句)

    1、使用WHERE子句 在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。WHERE子句在表名( FROM子句)之后给出,如下所示: 这条语句从products…

    数据库 2023年6月16日
    0119
  • gorm 版本对比

    两个版本 github.com/jinzhu/gorm v1.9.16 gorm.io/gorm v1.21.3 Open // jinzhu func Open(dialect …

    数据库 2023年6月9日
    0107
  • JAVA编程练习01作业

    2 、 输入一个圆半径(r),计算并输出圆的面积和周长。 3 、输入一个三位正整数n,输出其个位、十位和百位上的数字。 4 、根据性别和体重计算输血量。女性体重不超过50kg的输血…

    数据库 2023年6月11日
    0146
  • 2_JDBC

    使用客户端工具访问数据库, 需要手工建立连接, 输入用户名和密码登陆, 编写SQL语句, 点击执行, 查看操作结果(结果集或受行数影响) 在实际开发中, 当用户的数据发生改变时, …

    数据库 2023年6月11日
    055
  • Angel工作室ASP.NET(AngelExam)开源驾校考试系统正式发布

    一、Angel工作室ASP.NET(AngelExam)开源驾校考试系统简介 Angel工作室ASP.NET(AngelExam)驾校考试系统是基于asp.net mvc4.5(C…

    数据库 2023年6月14日
    070
  • python threading args参数报错must be an iterable, not int,解决方法

    错误代码: thread.append(threading.Thread(target=as_same_time, args=(0))) 分析: 因为as_same_time方法只…

    数据库 2023年6月11日
    070
  • 深入浅出分析 ArrayDeque

    作者:炸鸡可乐原文出处:www.pzblog.cn 一、摘要 在 jdk1.5 中,新增了 Queue 接口,代表一种队列集合的实现,咱们继续来聊聊 java 集合体系中的 Que…

    数据库 2023年6月14日
    086
  • MySQL Operator 01 | 架构设计概览

    高日耀 资深数据库内核研发毕业于华中科技大学,喜欢研究主流数据库架构和源码,并长期从事分布式数据库内核研发。曾参与分布式 MPP 数据库 CirroData 内核开发(东方国信),…

    数据库 2023年5月24日
    087
  • C语言学习笔记

    C语言学习笔记 预处理 #include include指令可以将另一个源文件的全部内容包含进来 include “stdio.h” #include 用尖…

    数据库 2023年6月14日
    0100
  • Java面向对象(下)作业

    首先我把题目先列到这里,可以仔细看一下题。 (1)设计一个名为Geometric的几何图形的抽象类,该类包括: ①两个名为color、filled属性分别表示图形颜色和是否填充。 …

    数据库 2023年6月11日
    0131
  • 数据库原理一—MySQL基本架构与索引

    MySQL基本架构 Server层包括连接器、查询缓存、分析器、优化器、执行器等,所有跨存储引擎的功能都在这一层实现。存储引擎层负责数据的存储和提取。其架构模式是插件式的,支持In…

    数据库 2023年6月6日
    071
  • 创建镜像(alpine版)+alpine

    podman用脚本和dockerfile做apache编译安装镜像 1.0安装介质 2.0 特点 2.0 基础命令 3.0 模式 podman用脚本和dockerfile做apac…

    数据库 2023年6月14日
    084
  • MySQL并行复制(MTS)原理(完整版)

    MySQL 5.6并行复制架构 MySQL 5.7并行复制原理 Master 组提交(group commit) 支持并行复制的GTID slave LOGICAL_CLOCK(由…

    数据库 2023年5月24日
    096
  • 【Java基础】 — Java遍历List四种方法的效率对比 【转载】

    1.遍历方法简介 Java遍历List的方法主要有四种: *for each *Iterator *loop without size *loop with size 注:这里我们…

    数据库 2023年6月6日
    0114
  • mqtt长连接报错32000

    背景 项目需要使用mqtt协议建立长连接,我是客户端,需要连上服务端同学的提供的地址;客户端使用的是paho提供的客户端sdk,如下: org.eclipse.paho org.e…

    数据库 2023年6月11日
    0107
  • 模板语法之传值取值

    模板语法之传值 变量相关使用:{{}}逻辑语法相关:{% %} 后端传值部分: def index(request): # 模版&amp…

    数据库 2023年6月14日
    061
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球