1.索引的本质

索引是帮组MYSQL高效获取数据的排好序的数据结构

二叉树

二叉树是树节点的度不大于2的有序树。它是一种最简单最重要的树。

image.png
二叉树的左节点始终小于父节点。二叉树的有节点始终大于等于父节点

image.png
对于单边递增的数据,二叉树会变成链表的形式。这个时候查询不会减少次数。所以也不会减少IO次数。这就是MYSQL没有使用二叉树的原因。

@Data
public class NodeTest {

    int fData;   //数据
    NodeTest leftChild;   //左节点
    NodeTest rightChild;  //右节点

    public NodeTest() {

    }

    public static void main(String[] args) {
        NodeTest nodeTest = new NodeTest();

    }



    static class Tree{
        private NodeTest root;

        public boolean insertNode(NodeTest root1,NodeTest nodeTest){
            if (root == null){
                root = nodeTest;
                return true;
            }else {
                // 代表不为null
                if (root1 == null){
                    root1 = root;
                }
                int fData1 = root1.getFData();
                if (fData1 > nodeTest.getFData()){
                    // 左节点
                    if (root1.getLeftChild() == null){
                        root1.setLeftChild(nodeTest);
                        return true;
                    }else {
                         // 左节点不为null
                        insertNode(root1.getLeftChild(),nodeTest);
                    }
                }else {
                    // 左节点
                    if (root1.getRightChild() == null){
                        root1.setRightChild(nodeTest);
                        return true;
                    }else {
                        // 左节点不为null
                        insertNode(root1.getRightChild(),nodeTest);
                    }
                }
            }
            return false;
        }

        public static void main(String[] args) {
            Tree tree = new Tree();
            NodeTest nodeTest = new NodeTest();
            nodeTest.setFData(3);
            boolean b = tree.insertNode(null, nodeTest);

            NodeTest nodeTest1 = new NodeTest();
            nodeTest1.setFData(5);
            tree.insertNode(null,nodeTest1);

            NodeTest nodeTest2 = new NodeTest();
            nodeTest2.setFData(2);
            tree.insertNode(null,nodeTest2);
            NodeTest nodeTest3 = new NodeTest();
            nodeTest3.setFData(3);
            tree.insertNode(null,nodeTest3);
            System.out.println(b);
        }
    }

}

红黑树

image.png

  1. 每个结点不是红色就是黑色
  2. 根节点是黑色的
  3. 如果一个节点是红色的,则它的两个孩子结点是黑色的(不会出现连在一起的红色节点)
  4. 对于每个结点,从该结点到其所有后代叶结点的简单路径上,均包含相同数目的黑色结点(在计算一条路径中黑色节点个数的时候要带上叶子节点,因为叶子节点也是黑色的,也就是空节点)。
  5. 每个叶子结点都是黑色的(此处的叶子结点指的是空结点)(为了保证空树也是红黑树)
  6. 红黑树确保没有一条路径会比其他路径长出俩倍(红黑树前面的性质保证了当前的性质)

虽然红黑树会根据性质做出对应的旋转,能够减少树的层级。但是对MYSQL而言存储的数据都是十万百万级别的。对应的树的层级还是很高。进行的IO次数也是不可避免的。所以MYSQL也没有使用红黑树(java中的Map和Set存储数据时如果一个桶上的数据大于8的时候会把链表转换为红黑树)。

B树

image.png
B 树也称 B- 树,它是一颗多路平衡查找树。我们描述一颗B树时需要指定它的阶数,阶数表示了一个结点最多有多少个孩子结点,一般用字母m表示阶数。当m取2时,就是我们常见的二叉搜索树。
一颗m阶的B树定义如下:
1)每个结点最多有m-1个关键字。
2)根结点最少可以只有1个关键字。
3)非根结点至少有 Math.ceil(m/2)-1个关键字。
4)每个结点中的关键字都按照从小到大的顺序排列,每个关键字的左子树中的所有关键字都小于它,而右子树中的所有关键字都大于它。
5)所有叶子结点都位于同一层,或者说根结点到每个叶子结点的长度都相同。

B-树每个节点都可以存储多个数据。而且也有红黑树的旋转属性。所以存储数据相同的情况下B数的层级更小。所以IO次数就会少。但是由于每个节点的数据都会存储真实的数据,真实数据往往比较大。所以导致一层节点存储的数据是有限的。所以MYSQL也没有用B树做为索引的存储结构。会用到下面的B+ 树。

B+ 树

image.png

B+ 树是B树的一个变种。B+ 树的非叶子节点不在存储数据。只进行数据索引。叶子节点结构也是有序的。并且每个元素会存储下一个元素的索引和上一个元素的索引。这样就大大增加了每一层非叶子节点存储的数据索引质量了。

假如一个节点能存储16KB、索引占用10b、数据占用1Kb则三层树可以存储多少?

结果\层BB+
1161600
216 * 16 = 2561600 * 1600 = 2560000
3256 * 16 = 40962560000 * 16 = 40960000

大概算了下发现B+ 比 B多存储了四个量级的数据。所以B+ 树IO次数在大数据两下比B树要小的多。

主键索引和联合索引的区别

  1. 主键索引是聚簇索引、联合索引是非聚簇索引。
  2. 主键索引推荐用int类型并且是自增的(减少B+树的旋转和调整)。并且聚簇索引叶子结点存储的是一条数据的所有值。非聚簇索引存叶子结点存储的是主键id。所以如果使用非聚簇索引查询数据,然后使用select * 还需要获取id数据后进行主键索引树中进行回表查询。所以会浪费一部分时间。
  3. 为啥非聚簇索引不存储一整行数据
    1. 为了保证数据一致性和节省空间。
      1. 因为如果索引都存储所有的数据。那每个索引在数据修改的时候都要更改为最新的数据。这个就无法保证了数据的一致性。
      2. 非聚簇索引不保存全部数据就可以减少很都空间。

索引覆盖

通俗来讲就是在执行某个查询语句时进行,在一个索引树(非聚簇索引)上就能查询到需要的字段、而无需回了,这就是索引覆盖。正确是使用好索引覆盖可以减少sql的执行时间。

比如:
创建一个user表:

creat table user(
	id int primary key,
	name varchar(20),
	sex varchar(5)
) engine=innodb;
ALTER TABLE user ADD INDEX index_name (name);: 添加name字段普通索引

如果查询
select id,name,sex from user where name = ‘小白’;
这个sql会先查询name索引树获取符合条件的id列表。然后再回表查询主键索引树获取sex字段数据。这就要拆线呢两次数据。
如果创建一个联合索引就可以不用多查询一次了。
ALTER TABLE user ADD INDEX index_name_sex (name,sex);: 添加name字段普通索引;
这样就拆线呢一次就能获取到所有需要的字段了。

结果:

所以在给表创建索引的时候最好创建联合索引。不要创建单个索引,一张表可以用两三个联合索引能概括全你所有的查询。不要使用select * 查询数据。每次查询最好返回自己有用的数据。不要返回无用的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/168939.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用cli批量下载GitHub仓库中所有的release

文章目录 1\. 引言2\. 工具官网3\. 官方教程4\. 测试用的网址5\. 安装5.1. 使用winget安装5.2. 查看gh是否安装成功了 6\. 使用6.1. 进行GitHub授权6.1.1. 授权6.1.2. 授权成功6.2 查看指定仓库中的所有版本的release6.2.1. 默认的30个版本6.2.2. 自定义的100个版本6.3 下载特定…

IDEA前端thymeleaf只显示部分数据库问题

只显示int类型的number&#xff0c;不显示string类型的price和weight 先看一下apple.html <!DOCTYPE html> <html xmlns:th"http://www.thymeleaf.org"> <head><meta charset"UTF-8"><title>User List</title> </…

【ROS】RViz2源码分析(三):核心类VisualizerApp

【ROS】郭老二博文之:ROS目录 1、简述 VisualizerApp包含了三个主要的功能: QApplication:程序中主要调用app_->processEvents()来处理刷新界面,处理闪屏VisualizationFrame:窗口类都在此;RosClientAbstractionIface包含rclcpp::Node:代表ROS节点2、VisualizationF…

使用 VPN ,一定要知道的几个真相!

你们好&#xff0c;我的网工朋友。 今天想和你聊聊VPN。在VPN出现之前&#xff0c;企业分支之间的数据传输只能依靠现有物理网络&#xff08;例如Internet&#xff09;。 但由于Internet中存在多种不安全因素&#xff0c;报文容易被网络中的黑客窃取或篡改&#xff0c;最终造…

FPGA实现双向电平转换

网上搜了一圈&#xff0c;好像没看到的类似的中文资料&#xff0c;不过MicroSemi有个文档AC349上给出了完整的解决方案&#xff0c;还有参考代码。 话不多说&#xff0c;看图&#xff1a; 欲知详情的朋友&#xff0c;请参考 AC349

一起Talk Android吧(第五百五十五回:Retrofit中的注解)

文章目录 1. 概念介绍2. 注解的分类与功能2.1 方法类注解2.2 参数类注解3. 内容总结各位看官们大家好,上一回中分享了一个Retrofit使用错误的案例,本章回中将 介绍Retrofit请求中的注解。闲话休提,言归正转,让我们一起Talk Android吧! 1. 概念介绍 我们在前面章回中介绍R…

YOLO改进系列之注意力机制(GAM Attention模型介绍)

模型结构 为了提高计算机视觉任务的性能&#xff0c;人们研究了各种注意力机制。然而以往的方法忽略了保留通道和空间方面的信息以增强跨维度交互的重要性。因此&#xff0c;liu提出了一种通过减少信息弥散和放大全局交互表示来提高深度神经网络性能的全局注意力机制。作者的目…

趣学python编程 (四、数据结构和算法介绍)

数据结构和算法在编程中非常重要。数据结构是组织和存储数据的方式&#xff0c;而算法是解决问题的方法和步骤。你要挑战的蓝桥杯&#xff0c;实际也是在设计算法解决问题。其实各种编程语言都只是工具&#xff0c;而程序的核心数据结构算法。犹如练武&#xff0c;数据结构和算…

算法学习 day26

第二十六天 最大子数组和 53. 最大子数组和 - 力扣&#xff08;LeetCode&#xff09; 动态规划问题 class Solution {public int maxSubArray(int[] nums) {int len nums.length;int[] dp new int[len];dp[0] nums[0];int res dp[0];for(int i 1; i < len; i){dp[i] …

【Java】异常处理(一)

&#x1f33a;个人主页&#xff1a;Dawn黎明开始 &#x1f380;系列专栏&#xff1a;Java ⭐每日一句&#xff1a;什么都不做&#xff0c;才会来不及 &#x1f4e2;欢迎大家&#xff1a;关注&#x1f50d;点赞&#x1f44d;评论&#x1f4dd;收藏⭐️ 文章目录 &#x1f4cb;前…

【运维篇】5.6 Redis server 主从复制配置

文章目录 0. 前言1. 配置方式步骤1: 准备硬件和网络步骤2: 安装Redis步骤3: 配置主服务器的Redis步骤4: 配置从服务器的Redis步骤5: 测试复制功能步骤6: 监控复制状态 2. 参考文档 0. 前言 在Redis运维篇的第5.6章节中&#xff0c;将讨论Redis服务器的主从复制配置。在开始之前…

Linux程序设计(上)

系列文章目录 文章目录 系列文章目录前言一、unix, linux, GNU, POSIXLinux程序 二、shellshell语法1.变量2.语句 函数命令命令的执行dialog工具-- 三、文件操作1. Linux 文件结构2. 系统调用和设备驱动程序3. 库函数4. 底层文件访问5. 标准I/O库6.格式化输入输出7. 文件和目录…

快速排序知识总结

快速排序思维导图&#xff1a; 快速排序算法模版&#xff1a; #include <iostream>using namespace std;const int N 1e5 10;int n; int q[N];void quick_sort(int q[], int l, int r) {if (l > r) return;int x q[(l r) / 2], i l - 1, j r 1;while (i < …

七天.NET 8操作SQLite入门到实战 - SQLite 简介

什么是SQLite&#xff1f; SQLite是一个轻量级的嵌入式关系型数据库&#xff0c;它以一个小型的C语言库的形式存在。它的设计目标是嵌入式的&#xff0c;而且已经在很多嵌入式产品中使用了它&#xff0c;它占用资源非常的低&#xff0c;在嵌入式设备中&#xff0c;可能只需要几…

记一次攻防实战渗透

经典开局一个登录框 由于漏洞应该还未修复。对于数据和相关网址打个码见谅一下 常规思路&#xff08;爆破&#xff09; 常规操作进行一波 尝试弱口令然后开始爆破 对于此种有验证码的爆破&#xff0c;可以借用一个bp插件。 captcha-killer-modified-jdk14.jar 具体使用我就…

【数据结构初阶】双链表

双链表 1.双链表的实现1.1结口实现1.2申请结点1.3初始化双链表1.4打印双链表1.5尾插1.6尾删1.7头插1.8头删1.9计算大小1.10查找1.11pos位置插入1.12删除pos位置1.12删除双链表 全部码源 1.双链表的实现 1.1结口实现 #include<stdio.h> #include<stdlib.h> #inclu…

2023下半年软件设计师考试知识点大全思维导图

软件设计师考试知识点大全思维导图 2023年下半年第一次机考 复习资料 以上是我在学习过程中根据自己的知识结构的特点及刷到的考题 做的导图&#xff0c;有需要的可以留言发原版的 mmap格式文件 方便自己拓展. 软考资料 这是网上找的资料 汇总免费放在这里 吧![ 链接&#x…

聊一聊go的单元测试

文章目录 概要一、测试框架1.1、testing1.2、stretchr/testify1.3、smartystreets/goconvey1.4、cweill/gotests 二、打桩和mock2.1、打桩2.2、mock2.2.1、mockgen 三、基准测试和模糊测试3.1、基准测试3.2、模糊测试 四、总结4.1、小结4.2、其他4.3、参考资料 概要 软件测试是…

java学习part06数组

62-数组-数组的概述_哔哩哔哩_bilibili 这篇 Java 基础&#xff0c;我吹不动了 - 掘金 (juejin.cn) 1.数组概念 重点 2.数组声明和初始化 new的时候要么给出静态初始化的数据{a,b,c}&#xff0c;要么给出动态初始化指定长度 [4]。 否则报错&#xff0c;初始化必须确定长度…

Redis字典实现

前言 字典又称符号表&#xff0c;关联数组或者映射(map)。是一种保存键值对的抽象数据结构。在字典中一个键和一个值进行关联。这些关联的值被称为键值对。 字典中每一个键都是独一无二的&#xff0c;没有重复的。我们可以通过键来查找值&#xff0c;更新值或者删除整个键值对等…