首页 > 数据库 >MySQL数据结构和索引

MySQL数据结构和索引

时间:2024-07-26 18:29:53浏览次数:11  
标签:使用 Tree 查询 索引 二叉树 MySQL 数据结构 节点

一、MySQL数据结构

InnoDB引擎

MySQL默认引擎是InnoDB引擎,这个引擎的主要特点是支持事务和行锁,

数据结构

2.1 二叉树(二叉查找树)

image.png

  • 二叉树是一种特殊的树,二叉树中每个节点的度都不能大于2,就是说每个节点最多只能有左右两个子节点
  • 当我们像二叉查找树储存数据的时候,是安装从大到小(或从小到大)的顺序保存的,这样有可能会形成一个单项链表的结构,搜索性能就会大打折扣。

为了解决平衡避免出现这种链表的结构,所以才有了平衡二叉树

2.2 平衡二叉树

平衡二叉树就能解决上面的问题
image.png
(1)非叶子节点最多拥有两个子节点
(2)非叶子节值大于左边子节点、小于右边子节点;
(3)树的左右两边的层级数相差不会大于1,
(4)没有值相等重复的节点

平衡二叉树会通过左旋右旋来平衡二叉树,避免变成单向链表结构,但过度要求平衡,会频繁的左右旋,
所以后面就出现了红黑树

2.3 红黑树

红黑树只是减少左右旋,本身还是会左旋和右旋
image.png

  • 性质1:每个节点要么是红色,要么是黑色。
  • 性质2:根节点是黑色。
  • 性质3:每个叶子节点(NIL节点,也就是 NULL 节点)是黑色。
  • 性质4:如果一个节点是红色的,则它的两个子节点都是黑色的(从每个叶子到根的所有路径上不能有两个连续的红色节点)。
  • 性质5:从任一节点到其每个叶子的所有简单路径都包含相同数量的黑色节点。
  1. 平衡性
    • 红黑树通过上述性质确保了树的高度保持在 O(log n),其中 n 是树中的节点数。
    • 这种性质保证了红黑树的操作(查找、插入、删除)的时间复杂度为 O(log n)。
  2. 插入操作
    • 插入新节点时,新节点默认着色为红色。
    • 插入后,如果破坏了红黑树的性质,需要通过旋转和重新着色来恢复性质。
    • 可能的旋转操作包括左旋、右旋、左右旋和右左旋。
  3. 删除操作
    • 删除节点可能导致红黑树失去平衡。
    • 删除后,需要通过旋转和重新着色来恢复性质。
    • 删除操作可能涉及复杂的颜色调整和旋转。
  4. 旋转操作
    • 左旋(Left Rotation):如果需要将一个节点的右子节点提升到更高的位置,可以进行左旋。
    • 右旋(Right Rotation):如果需要将一个节点的左子节点提升到更高的位置,可以进行右旋。
    • 左右旋(Left-Right Rotation):先对节点的左子节点进行左旋,然后对节点本身进行右旋。
    • 右左旋(Right-Left Rotation):先对节点的右子节点进行右旋,然后对节点本身进行左旋。

2.4 B-Tree(平衡多路查找树)


每一个节点都储存完整的一条数据,这是和B+Tree最明显的区别,对于范围查询效率不高。
InnoDB存储引擎中有页(Page)的概念,页是其磁盘管理的最小单位。InnoDB存储引擎中默认每个页的大小为16KB(16384/1024),InnoDB在把磁盘数据读入到内存时会以页为基本单位

假如说:每个磁盘块的大小是1k(一个指针+一个数据节点是1k),那么一页就是有16个磁盘块,如果每次加载一页,也有16个指针,而且每个指针指向一个磁盘块(第二层),那么对于一个三层的b-树来说。能存储的节点数就是:16X16X16 = 4096

当需要查询的数据很多时,也就是十万百万级别的时候,B-Tree结构对于查询的效率就不怎么管用了,因为这个时候树的层级会很高,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数
所以后面的B+Tree进一步优化这件事。

2.5 B+Tree


和B-Tree的主要区别是B+Tree的所有数据存储在叶子结点中,非叶子节点只存储键值信息和指针,而有数据的叶子结点会形成一个双向链表的结构,可以范围查询。

InnoDB存储引擎中页的大小为16KB,一般表的主键类型为INT(占用4个字节)或BIGINT(占用8个字节),指针类型也一般为4或8个字节,也就是说一个页(B+Tree中的一个节点)中大概存储16KB/(8B+8B)=1K个键值(因为是估值,为方便计算,这里的K取值为1000。也就是说一个深度为3的B+Tree索引可以维护1000 * 1000 * 50(最后一层每个磁盘块存多少数据节点,假设是50个) = 5千万条记录。深度一般是三到四层

特点:

  1. 所有的叶子结点中包含了全部关键字的信息,非叶子节点只存储键值信息,及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接,所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B树的非终节点也包含需要查找的有效信息)
  2. 所有叶子节点之间都有一个链指针。
  3. 数据记录都存放在叶子节点中。

二、索引

什么是索引?

数据库管理系统(DBMS)中用于加快数据检索速度的一种数据结构,InnoDB用的是B+Tree的结构
特点:

  • 占用磁盘空间
  • 大大提高查询效率,减少磁盘IO
  • 降低增删改的效率

索引的类型

  • 聚簇索引(Clustered Index):数据按照索引顺序存储,每个表只能有一个聚簇索引。
  • 非聚簇索引(Nonclustered Index):数据和索引分开存储,一个表可以有多个非聚簇索引。
  • 唯一索引(Unique Index):保证索引中的键值唯一。
  • 全文索引(Full-text Index):用于全文搜索,支持复杂的内容搜索

聚簇索引和非聚簇索引

聚簇索引,每个节点都存有完整的数据
非聚簇索引,只存了Key和指针和ID

回表和索引覆盖:
回表:当查询一个或一些数据的时候,如:select * from table where name = Joker 的时候,假设索引字段是 name,非聚簇索引查到了名字,但需要的是全部的数据,这时候和根据查到ID进行聚簇索引查询,这就是回表。
索引覆盖,以上,如果是 select name from table where name = Joker,需要的数据刚好可以通过非聚簇索引查询,不需要回表,这时候就是索引覆盖。(所以MySQL优化中有一个要求是:避免使用select *)

索引失效

可以使用Explain来查询是否使用了索引
避免索引失效对于提高数据库查询性能至关重要。以下是几种常见的方法来确保索引的有效使用:

1. 最左前缀原则

  • 全值匹配:确保 WHERE 子句中的条件与索引列的顺序相匹配。
  • 不要跳过索引列:如果索引是复合索引(多个列组成的索引),查询时应该从最左边的列开始,依次向右进行匹配,不能跳过中间的列。

2. 避免在索引列上进行操作

  • 不要在索引列上使用函数:例如 WHERE UPPER(column) = 'value'
  • 不要在索引列上进行表达式操作:例如 WHERE column * 2 = 10
  • 避免类型转换:确保查询中的常量与索引列的数据类型一致。

3. 范围条件后的列不可用

  • 如果使用了范围条件(如 <, <=, >, >=, BETWEEN, LIKE 开头的模式匹配等),则在范围条件之后的索引列无法被使用。

4. 使用覆盖索引

  • 覆盖索引:当索引包含了所有需要查询的字段时,可以避免回表查询(即不需要再从主键索引中查找数据)。
  • 减少 SELECT * 的使用:明确指定所需的列,而不是使用 SELECT *

5. LIKE 语句的使用

  • 避免以通配符开头:如果使用 LIKE '%value%',则索引可能失效。但如果使用 LIKE 'value%'LIKE '%value',则索引仍可有效利用。

6. 数据类型的匹配

  • 确保索引列和查询中的值的数据类型一致,避免隐式类型转换。

7. 避免使用 NOT IN 和 NOT EXISTS

  • 使用 NOT INNOT EXISTS 可能会导致索引失效。可以尝试使用 LEFT JOINNOT EXISTS 结合子查询的方式代替。

8. 选择合适的数据类型

  • 为索引列选择合适的数据类型,尤其是当有多种数据类型可以选择时,选择占用空间较小的数据类型可以节省存储空间,提高索引的效率。

9. 维护索引

  • 定期检查和优化索引,例如使用 ANALYZE TABLEOPTIMIZE TABLE 命令。

10. 避免使用 SELECT *

  • 明确列出需要查询的字段,减少不必要的数据传输。

11. 使用全文索引

  • 对于全文搜索,使用全文索引(如 FULLTEXT 索引)。

12. 限制使用 OR

  • 当使用 OR 时,确保至少有一个条件能够使用有效的索引。

通过遵循以上原则,可以有效地避免索引失效的问题,从而提升数据库查询的性能。

标签:使用,Tree,查询,索引,二叉树,MySQL,数据结构,节点
From: https://www.cnblogs.com/JokerWorld/p/18325995

相关文章

  • MySQL第一阶段:多表查询、事务
            继续我的MySQL之旅,继续上篇的DDL、DML、DQL、以及一些约束,该到了多表查询和事务的学习总结,以及相关的案例实现,为未来的复习以及深入的理解做好知识储备。目录多表查询连接查询内连接外连接子查询事务 事务简介事务操作事务四大特征多表查询多......
  • 可持久化数据结构
    可持久化数据结构简介分类部分可持久化所有版本都可以访问,但是只有最新版本可以修改。完全可持久化所有版本都既可以访问又可以修改。实际应用几何计算(扫描线),字串处理(合并操作rope),版本回溯,函数式编程。可持久化线段树引入[P3834【模板】可持久化线段树2]首先考虑静态......
  • MySQL索引、事务(数据库管理与高可用)
    一、索引的概念索引:排序的列表,对数据进行快速的查询;针对不同的产品需求,或者不同的数据库结构,会创建不同的索引;1:普通索引(默认索引)2:唯一索引(可以多个)3:主键索引(只能一个)4:组合索引(最左查询)5:全文索引oracle:B树索引将表一份为二进行查询;701--3536--701--1718--35先把......
  • 【MySQL进阶之路 | 高级篇】表级锁之S锁,X锁,意向锁
    1.从数据操作的粒度划分:表级锁,页级锁,行锁为了尽可能提高数据库的并发度,每次锁定的数据范围越小越好,理论上每次只锁定当前操作的数据的方案会得到最大的并发度,但是管理锁是很耗资源的事情(涉及获取、检查、释放锁等动作)。因此数据库系统需要在高并发响应和系统性能两方面进行......
  • 【MySQL进阶之路 | 高级篇】行锁之记录锁和间隙锁
    1.InnoDB的行锁行锁(rowlock)也称为记录锁。顾名思义,就是锁住某一行(某个记录row)。需要注意的是,MySQL服务层并没有行锁机制,行级锁只在存储引擎层实现。优点:锁定力度小,发生锁冲突概率低,可以实现的并发度高。缺点:对于锁的开销比较大,加锁会比较慢,容易出现死锁的情况。InnoDB与M......
  • MySQL 学习笔记 进阶(索引 下)
    索引 索引-分类 在InnoDB中存储引擎中,根据索引的存储形式,又可以分为以下几种: 聚集索引选取规则:如果存在主键,主键索引就是聚集索引。如果不存在主键,将使用第一个唯一(UNIQUE)索引作为聚集索引。如果表没有主键,或没有合适的唯一索引,则InnoDB会自动生成一个rowid作为隐藏......
  • Fatal error: Call to undefined function mysql_connect() in …
    错误记录:Fatalerror:Calltoundefinedfunctionmysql_connect()in…错误原因:运行环境问题解决方案:你的PHP不支持mysql_connect()函数。PHP是一种模块化的设计,除了核心的内容,其他都是可选的。之所以不支持,是因为在编译PHP时没有加入对MYSQL数据库的支持。原因2:......
  • MySQL数据库安装及使用
    MySQL安装在线安装ubuntusudoapt-getinstallmysql-server#服务器sudoapt-getisntallmysql-client#客户端sudoapt-getinstalllibmysqlclient-dev#开发接口redhatyuminstallmysql-serveryuminstallmysql-clientyuminstalllibmy......
  • 数据结构 二叉树 前 中 后 序列
    简单二叉树的遍历如果看完还是不太懂就观看速成视频https://www.bilibili.com/video/BV1Ub4y147Zv/?spm_id_from=333.337.search-card.all.click&vd_source=e5f8765d50fb89ef04eb150bd76075b5引用资料文献链接放到篇尾简单术语解释节点(Node):二叉树中的一个元素,包含值和......
  • Rocky Linux 8安装MySQL8
    先去mysql官网:https://downloads.mysql.com/archives/community/选择对应的版本下载,然后上传到Linux机器上或者直接在linux上wgethttps://downloads.mysql.com/archives/get/p/23/file/mysql-8.4.0-1.el8.x86_64.rpm-bundle.tar下载资源使用tar-xvfmysql-8.4.0-1.......