元月's blog 元月's blog
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多

元月

临渊羡鱼,不如退而结网
首页
  • 基础
  • 并发编程
  • JVM
  • Spring
  • Redis篇
  • Nginx篇
  • Kafka篇
  • Otter篇
  • Shardingsphere篇
  • 设计模式
  • MySQL
  • Oracle
  • 基础
  • 操作系统
  • 网络
  • 数据结构
  • 技术文档
  • Git常用命令
  • GitHub技巧
  • 博客搭建
  • 开发工具
更多
  • MySQL

    • MySQL的存储引擎和索引结构
      • 一、简介
      • 二、存储引擎
        • 2.1、MyISAM
        • 2.2、InnoDB
      • 三、索引分类
        • 3.1、按数据结构分类
        • 3.2、按物理存储分类
        • 3.3、按字段特性分类
        • 3.4、按字段个数分类
      • 四、常见问题
        • 4.1、InnoDB和MyISAM的区别
        • 4.2、为什么建议InnoDB表要有主键,并且推荐使用整型的自增主键?
        • 4.3、为什么非主键索引叶子节点存储的是主键值?
    • 一条SQL的平凡之路--执行篇
    • 一条SQL的平凡之路--优化篇
    • MySQL的事务、锁和MVCC机制
    • MySQL的主从复制原理详解
    • MySQL高可用架构
    • ShardingJDBC读写分离与分库分表实战
  • Oracle

  • 数据库
  • MySQL
元月
2022-11-24
目录

MySQL的存储引擎和索引结构

# MySQL的存储引擎和索引结构

# 一、简介

MySQL官方对索引的定义是:索引(Index)是帮助MySQL高效获取数据的数据结构。

在MySQL中索引是在存储引擎层实现的,而不是在服务器层实现的,所以不同存储引擎具有不同的索引类型和实现

# 二、存储引擎

# 2.1、MyISAM

MyISAM [maiˈzæm] 的索引文件和数据文件是分离的,叶子节点中存放数据地址。

文件结构如下:

.frm 表定义文件

.myi 索引文件

.myd 数据文件

# 2.2、InnoDB

InnoDB表必须要有聚集索引,默认在主键字段上建立聚集索引,在没有主键字段的情况下,表的第一个非空的唯一索引将被建立为聚集索引,在前两者都没有的情况下,InnoDB将自动生成一个隐藏的自增id列,并在此列上建立聚集索引。

文件结构如下:

.frm 表定义文件

.ibd 索引数据文件

# 三、索引分类

# 3.1、按数据结构分类

MySQL索引按数据结构分类可分为:B+tree索引、Hash索引、Full-text索引

1、B+tree索引

a. 非叶子节点上不存储行记录,仅存索引;这就使得非叶子节点上可以存储更多的键值,相应的树的阶数(节点的子节点树)就会更大,树也就会变得更矮更胖。这样一来我们查找数据进行磁盘I/O的次数就会大大减少,数据查询的效率也会更快。

b. 叶子节点上有序存储行记录,通过链表链接,支持范围查询。

一次磁盘IO读取一页数据,一页数据大小为16KB,假设非叶子结点每个索引字段 8字节+4字节,每页大概可以放1100条数据,叶子结点每条数据占1K,每页大概可以放16条数据。一个高度为3的 B+tree 可以存放近2kw条数据,只需要经过三次磁盘IO,另外在一些版本的数据库,根结点/非叶子结点会常驻内存,数据的查询效率非常快

这也是为什么不建议在表记录上有大字段

2、Hash索引

Hash索引在精确查询时的效率要远高于B+Tree索引,但是也存在一些明显的问题:

  1. Hash索引仅仅能满足等值查询,不能进行范围查询

  2. Hash索引无法通过操作索引来排序

  3. 组合Hash索引不能利用部分索引键进行查询

  4. Hash索引依然需要回表扫描

3、Full-text索引

Full-text索引一般使用倒排索引实现

# 3.2、按物理存储分类

1、聚集索引

聚簇索引就是按照每张表的主键构造 B+tree,叶子节点中存放表的数据记录,聚集索引的叶子节点被称为数据页

2、非聚集索引(二级索引)

非聚集索引的结构和聚集索引基本相同(非叶子结点存储的都是索引指针),区别在于叶子节点存放的是数据主键而不是行数据。因此在使用非聚集索引进行查找时,需要先查找到主键值,然后再到聚集索引中进行查找。

两种索引的区别:

1、聚集索引的叶子结点包含行记录数据,而非聚集索引的叶子结点只包含主键字段。

2、聚集索引一个表只能有一个,而非聚集索引一个表可以存在多个。

什么是索引覆盖?

索引覆盖就是指索引的叶子节点已经包含了要查询的数据,没必要再回表查询。常见的方式就是建立联合索引(组合索引),实现索引覆盖,从而避免回表查询。

# 3.3、按字段特性分类

MySQL索引按字段特性分类可分为:主键索引(PRIMARY KEY)、唯一索引(UNIQUE)、普通索引(INDEX)、全文索引(FULLTEXT)。

1、主键索引(PRIMARY KEY)

建立在主键上的索引被称为主键索引,一张数据表只能有一个主键索引,索引列值不允许有空值,通常在创建表时一起创建。

2、唯一索引(UNIQUE)

建立在UNIQUE字段上的索引被称为唯一索引,一张表可以有多个唯一索引,索引列值允许为空,列值中出现多个空值不会发生重复冲突。

3、普通索引(INDEX)

建立在普通字段上的索引被称为普通索引。

4、全文索引(FULLTEXT)

MyISAM 存储引擎支持Full-text索引,用于查找文本中的关键词,而不是直接比较是否相等。Full-text索引一般使用倒排索引实现,它记录着关键词到其所在文档的映射。

InnoDB 存储引擎在 MySQL 5.6.4 版本中也开始支持Full-text索引。

# 3.4、按字段个数分类

MySQL索引按字段个数分类可分为:单列索引、联合索引(也叫复合索引、组合索引)。

1、单列索引

建立在单个列上的索引被称为单列索引。

2、联合索引(复合索引、组合索引)

建立在多个列上的索引被称为联合索引,又叫复合索引、组合索引。

在MySQL中使用联合索引时要遵循最左前缀匹配原则。

所以我们需要注意如下几个方面:

a. 实际业务场景中创建联合索引时,我们应该把识别度比较高的字段放在前面,提高索引的命中率,充分的利用索引。

b. 创建联合索引后,该索引的任何最左前缀都可以用于查询。比如当你有一个联合索引(col1, col2, col3),该索引的所有最左前缀为(col1)、(col1, col2)、(col1, col2, col3),包含这些列的所有查询都会使用该索引进行查询。

c. 虽然联合索引可以避免回表查询,提高查询速度,但同时也会降低表数据更新的速度。因为联合索引列更新时,MySQL不仅要保存数据,还要维护一下索引文件。所以不要盲目使用,应根据业务需求来创建。

# 四、常见问题

# 4.1、InnoDB和MyISAM的区别

  1. InnoDB支持事务,MyISAM不支持
  2. InnoDB支持行锁,而MyISAM不支持
  3. InnoDB支持外键,而MyISAM不支持
  4. InnoDB是聚集索引,数据文件和索引文件在一起的,而MyISAM是非聚集索引,数据文件是分离的
  5. InnoDB不存储表的行数,而MyISAM会存放表的行数

# 4.2、为什么建议InnoDB表要有主键,并且推荐使用整型的自增主键?

1、若无主键,MySQL帮你维护一个隐藏列,MySQL资源珍贵,请自行维护

2、使用整型是因为整型占用空间小,比较速度快

3、使用自增是为了避免页分裂

# 4.3、为什么非主键索引叶子节点存储的是主键值?

一致性和节省存储空间

参考资料:

https://blog.csdn.net/u013635487/article/details/122469255

#MySQL#数据库
一条SQL的平凡之路--执行篇

一条SQL的平凡之路--执行篇→

最近更新
01
otter二次开发-支持按目标端主键索引Load数据
08-03
02
mvnw简介
06-21
03
gor流量复制工具
06-03
更多文章>
Theme by Vdoing | Copyright © 2022-2024 元月 | 粤ICP备2022071877号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式