[MySQL#11] 索引底层(2) | B+树 | 索引的CURD | 全文索引

目录

1.B+树的特点

索引结构

复盘

其他数据结构的对比

B树与B+树总结

聚簇索引与非聚簇索引

辅助索引

2. 索引操作

主键索引

1. 创建主键索引

第一种方式

第二种方式

第三种方式

2. 查询索引

第一种方法

第二种方法

第三种方法

3. 删除索引

删除主键索引

删除其他索引

4. 特点

唯一索引

1. 创建

第一种方式

第二种方式

第三种方式

2. 删除唯一索引

3. 特点

普通索引

第一种方式

第二种方式

第三种方式

9. 普通索引的特点

复合索引

多列索引的创建

复合索引的工作原理

复合索引的应用场景

索引创建原则

索引总结

3.全文索引

创建

查询与全文索引

总结


1.B+树的特点

叶子节点保存有数据,非叶子节点不要数据

  • 非叶子节点:不存数据,只存储目录项,可以存储更多的目录项。
  • 目录页:一个目录页可以管理更多的叶子Page,使树更矮胖,减少I/O次数,提高效率。

叶子节点全部用链表级联起来

  • 链表级联:叶子节点用链表级联,便于进行范围查找,提高查询效率。
索引结构
  • InnoDB的索引结构:MySQL InnoDB存储引擎使用B+树作为索引结构。
  • 主键索引:默认情况下,如果没有指定主键,MySQL会自动生成一个隐藏列作为主键。
  • 普通索引:用户可以建立其他列的索引,这些索引也是B+树结构。
复盘
  • Page分类:Page分为目录页和数据页。目录页只放各个下级Page的最小键值
  • 查找过程自顶向下查找,只需加载部分目录页到内存,大大减少I/O次数。
  • 索引构建:构建索引就是在MySQL内存中构建B+树,以指定列作为key值。
其他数据结构的对比
  • 链表:线性遍历,效率低。
  • 二叉搜索树:可能退化成线性结构,效率不稳定。
  • AVL & 红黑树:虽然平衡,但树高较高,I/O次数多。
  • Hash:适合点查询,但在范围查找方面表现不佳。

B+ vs B

B树

B+树

  • B+树非叶子节点不存数据,数据都在叶子节点,并且所有叶子节点用链式结构连接起来。
  • 而B树每一个节点内既包含目录项又包含数据,所有B树除了叶子节点有数据路上节点也会包含数据。还有B树的叶子节点是没有被链式结构连接起来的。

那为什么mysql没有使用B树而用的B+呢?

第一,mysql认为如果给非叶子节点增加数据,也就意味着单个page里能够保存的目录项变少了,意味着一个页目录所能管理的子目录子page就变少了,一旦变少了,在逻辑上这棵B树会比B+树更高一些更瘦一些,也就意味从根道叶子节点搜索的时候,要经过更多的节点要经历更多次IO,算法和IO带来的成本,永远都是IO带来的成本更高的。

第二,B树的叶子节点没有相连,也就意味着想进行范围查找,依旧要重新遍历这颗B树。而一旦重新遍历B树也就注定在遍历的时候需要每次查B树,可能有些page并不在内存里,又需要在进行IO,同时每次查效率也很慢,不像B+树找到起始位置线性遍历,一定拿到的是有效范围内所有数据。

B树与B+树总结
  • B树:每个节点内既包含目录项又包含数据,树高较高,I/O次数多。
  • B+树:非叶子节点不存数据,树更矮,I/O次数少,叶子节点用链表级联,便于范围查找。

例:演示一个Max.Degree=3 的B+树

数据结构演示链接

聚簇索引与非聚簇索引

非聚簇索引

  • MyISAM存储引擎,索引和数据分离,适合某些场景
  • MyISAM 引擎同样使用B+树作为索引结果,叶节点的data域存放的是数据记录的地址。下图为 MyISAM表的主索引, Col1 为主键。

聚簇索引

  • InnoDB存储引擎,数据和索引放在一起,提高查询效率。

下面我们见一下现象,文件结构

InnoDB

  • test1.frm:表结构数据。
  • test1.ibd:主键索引和用户数据。

MyISAM(分离)

CREATE TABLE myisam_test (id INT PRIMARY KEY
) ENGINE=MyISAM;
  • test2.frm:表结构数据。
  • test2.MYD:数据记录。
  • test2.MYI:索引 数据指针。

辅助索引
  • InnoDB:辅助索引的叶子节点只包含对应记录的主键值,需要进行回表查询。
  • MyISAM:辅助索引和主键索引类似,叶子节点包含数据记录的地址

注意:

  • 所以一张表没有指明任何主键,mysql默认会给表添加默认主键也会以B+树结构呈现,只不过我没有设立主键就只能线性遍历。
  • 如果我们指明主键默认我们的表会配上主键索引,会以我们自己设置的主键为key值设立主键索引。如果我们指明主键索引,未来还想给其他列设置索引,我们可以手动添加。
  • 添加之后会在mysql内部重新构建B+树,以MyISAM为例会指向记录,如果是InnoDB保存的是主键值方便我们快速索引。换句话说,
  • 一个表可能会建立主键索引或者其他普通索引,不管建立任何索引最终在mysql中一张表可能会有多颗B+树。
  • 索引语法上分三类:主键索引、唯一键索引、普通索引,但其实宏观上就两类一个是主键索引,指明就用主键的没有指明就用默认的。一个是普通索引,包括唯一索引。

2. 索引操作

主键索引

1. 创建主键索引

第一种方式

创建表时直接指定 primary key

create table test1(id int primary key, name varchar(30));
  • 说明:在字段名后指定 primary key,MySQL会根据该列构建主键索引。
第二种方式

在创建表的最后指定某列或某几列为主键索引

create table test2(id int, name varchar(30), primary key(id));
  • 说明:在表定义的最后指定某列或某几列为主键。
第三种方式

创建表以后再添加主键

create table test3(id int, name varchar(30));
alter table test3 add primary key(id);
  • 说明:先创建表,再通过 alter table 添加主键。

2. 查询索引

第一种方法

使用 show keys from 表名

show keys from test1;
第二种方法

使用 show index from 表名

show index from test1;
第三种方法

使用 desc 表名

desc test1;
  • 说明:信息较为简略,主要用于查看表结构。

3. 删除索引

删除主键索引
  • 第一种方法
alter table 表名 drop primary key;
删除其他索引
  • 第二种方法
alter table 表名 drop index 索引名;
  • 第三种方法
drop index 素引名 on 表名;

4. 特点

  • 一个表中最多有一个主键索引
  • 主键索引的效率高(主键不可重复)
  • 创建主键索引的列,值不能为null,且不能重复
  • 主键索引的列基本上是int

唯一索引

1. 创建

第一种方式
  • 在表定义时指定 unique 唯一属性
create table test4(id int primary key, name varchar(30) unique);
第二种方式
  • 在表定义的最后指定某列或某几列为 unique
create table test5(id int primary key, name varchar(30), unique(name));
第三种方式
  • 创建表以后再添加唯一键
create table test6(id int primary key, name varchar(30));
alter table test6 add unique(name);
  • 说明:添加唯一键后,表中会有两个B+树,一个是主键索引,另一个是以指定列构建的唯一索引。

2. 删除唯一索引

  • 使用 alter table 删除索引
alter table 表名 drop index 索引名;
  • 说明:唯一索引的删除方式与普通索引相同,不能使用 drop unique

为什么说这个呢,我们发现主键很特殊,构建是 add primary key,删除是 drop primary key 这没问题。

  • 但是删除唯一键不能用drop unique,用的是drop index。
  • 未来你会发现我们删除普通索引用的也是drop index。
  • 说明unique索引本身也是一个普通索引。只不过指明它是uniqe是为了照顾表中的约束关系。
  • 其实在索引层面,普通索引和唯一键索引都是一般索引。
  • 最特殊的就是主键索引。

3. 特点

  • 一个表中可以有多个唯一索引(唯一是指 无重复数据)
  • 查询效率高
  • 如果在某一列建立唯一索引,必须保证这列不能有重复数据
  • 如果一个唯一索引上指定 not null,等价于主键索引

普通索引

创建

第一种方式
  • 在表定义的最后指定某列为索引
create table test8(id int primary key,name varchar(20),email varchar(30),index(name)
);
第二种方式
  • 创建完表以后指定某列为普通索引
create table test9(id int primary key,name varchar(20),email varchar(30)
);
alter table test9 add index(name);
  • 说明:普通索引和唯一索引在结构上没有区别,都是B+树。
第三种方式
  • 创建一个索引名为 idx_name 的索引
create table test10(id int primary key,name varchar(20),email varchar(30)
);
create index idx_name on test10(name);
9. 普通索引的特点

  • 一个表中可以有多个普通索引,普通索引在实际开发中用得较多
  • 如果某列需要创建索引,但该列有重复值,应使用普通索引

复合索引

多列索引的创建

问题:创建索引时只能在某一列创建吗?如果表中有多列信息,是否可以创建以多列为key值的索引结构?

答案:可以!

示例

create table test11(id int primary key,name varchar(20),email varchar(30)
);
create index idx_name_email on test11(name, email);

解释

  • 创建复合索引:我们nameemail 两列建立索引。
  • 索引数量:创建复合索引后,表中显示有三个索引,但这并不意味着新增了两个B+树。
复合索引的工作原理
  • 单一B+树复合索引实际上只构建了一颗B+树,而不是两颗。
  • 键值组合:这颗B+树的键值是由 nameemail 两列值组合而成。
  • 搜索条件:在搜索时,这两列必须同时满足条件才能找到目标记录。

示例

  • 索引名称:复合索引的名称默认为 idx_name_email,以多列中的第一列 name 作为索引名称。
  • 删除索引:删除复合索引时,只需一次操作即可删除整个复合索引。
alter table test11 drop index idx_name_email;
复合索引的应用场景

何时使用复合索引

  • 避免回表:InnoDB普通索引的叶子节点放的是表的主键的key值,这意味着需要回表查询。但如果以 nameemail 构建复合索引,未来高频查询时,可以直接通过 nameemail 查找,数据本身就在这颗复合索引的B+树里,无需回表。
  • 索引覆盖如果查询条件和返回值都在复合索引的列中,可以直接从索引中获取数据,无需回表,这种情况称为索引覆盖。
  • 最左匹配原则:MySQL在索引匹配时是从左侧开始向右匹配。例如,可以按 namenameemail 查找,但不能直接按 email 查找。

示例

  • 查询姓名和QQ号
create table test12(id int primary key,name varchar(20),qq varchar(20)
);
create index idx_name_qq on test12(name, qq);
    • 查询:通过 name 查找 qq 号,可以直接从复合索引中获取数据,无需回表。
select qq from test12 where name = '张三';
索引创建原则

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

2. 唯一性太差的字段:不适合单独创建索引,即使频繁作为查询条件。

  • 示例:给性别打上索引,但性别只有男和女,构建出的B+树并不优秀。

3. 更新非常频繁的字段:不适合作创建索引。

  • 示例:考试信息更改太频繁,索引创建出来是为了方便查询,频繁修改不仅影响数据,还会调整索引结构。

4. 不会出现在 where 子句中的字段:不应创建索引。

  • 示例:某些字段从未在 where 子句中出现,创建索引没有意义。

适合创建索引

  • 高频读取
  • 低频修改
  • 唯一性高
  • 避免冗余:避免在唯一性差或更新频繁的字段上创建索引。

索引总结

  • 主键索引:一个表中最多一个,效率高,值不能为null且不能重复。
  • 唯一索引:一个表中可以有多个,查询效率高,值不能重复。
  • 普通索引:一个表中可以有多个,适用于有重复值的列。
  • 复合索引:将多列值放在一起充当键值,构建B+树,查找时必须满足多列值一致。

3.全文索引

B+树索引

  • 键值字段:通常较短,如 idqq 等。
  • 用途:用于快速找到一条记录或记录中的某一列或几列。

全文索引

  • 键值字段:通常较长,如文章内容,每行内容可能包含数千个字符。
  • 用途:用于在长文本中查找特定的内容,而不仅仅是找到一条记录。
创建

当对文章字段或有大量文字的字段进行检索时,会使用到全文索引。MySQL提供全文索引机制,但有以下要求:

  • 存储引擎:必须是MyISAM
  • 语言支持:默认支持英文,不支持中文。如果需要对中文进行全文检索,可以使用sphinx的中文版(coreseek)。

示例

CREATE TABLE articles (id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR(200),body TEXT,FULLTEXT (title, body)
) engine=MyISAM;

插入数据

INSERT INTO articles (title, body) VALUES('MySQL Tutorial', 'DBMS stands for DataBase ...'),('How To Use MySQL Well', 'After you went through a ...'),('Optimizing MySQL', 'In this tutorial we will show ...'),('1001 MySQL Tricks', '1. Never run mysqld as root. 2. ...'),('MySQL vs. YourSQL', 'In the following database comparison ...'),('MySQL Security', 'When configured properly, MySQL ...');
查询与全文索引

普通查询

select * from articles where body like '%database%';
  • 问题:虽然查询出数据,但没有使用到全文索引。
  • 检查:可以使用 explain 工具查看查询是否使用了索引。

使用全文索引查询

select * from articles where match(title, body) against ('database');

设置

  • match:匹配条件。
  • against:匹配的关键字,这里是 database

检查

explain select * from articles where match(title, body) against ('database');

解释

  • typefulltext 表示使用了全文索引。
  • key:表示使用了哪个索引。
总结
  • 全文索引:用于在长文本中查找特定内容,特别适用于文章或大量文字的字段。
  • 创建:需要使用 FULLTEXT 关键字,并且表的存储引擎必须是MyISAM。
  • 查询:使用 matchagainst 关键字进行全文索引查询,可以显著提高查询效率。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能基础-opencv-图像处理篇

一.图像预处理 图像翻转 cv2.flip 是 OpenCV 库中的一个函数,用于翻转图像。翻转可以是水平翻转、垂直翻转或同时水平和垂直翻转。这个函数接受两个参数:要翻转的图像和一个指定翻转类型的标志。 img cv2.imread(../images/car2.png) #翻转 0&#xf…

【机器学习】嘿马机器学习(科学计算库)第4篇:Matplotlib,学习目标【附代码文档】

本教程的知识点为:机器学习(常用科学计算库的使用)基础定位 机器学习概述 机器学习概述 1.5 机器学习算法分类 1 监督学习 机器学习概述 1.7 Azure机器学习模型搭建实验 Azure平台简介 Matplotlib 3.2 基础绘图功能 — 以折线图为例 1 完善原…

平衡二叉树(递归)

给定一个二叉树,判断它是否是 平衡二叉树.平衡二叉树 是指该树所有节点的左右子树的深度相差不超过 1。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:true示例 2: 输入:root [1,2,2,3,3,null,null,4…

Python数据分析案例61——信贷风控评分卡模型(A卡)(scorecardpy 全面解析)

案例背景 虽然在效果上,传统的逻辑回归模型通常不如现代的机器学习模型,但在风控领域,解释性至关重要。逻辑回归的解释性是这些“黑箱”模型所无法比拟的,因此,研究传统的评分卡模型依然是有意义的。 传统的评分卡模型…

Weblogic漏洞复现(Vulhub)

0x00前言 1.docker 安装 Docker的安装_docker安装-CSDN博客 2.docker的镜像 1.可以在阿里云上的容器服务找到镜像源。 2.也可以使用下面的镜像源,时快时慢不稳定。 {"registry-mirrors":["https://docker.registry.cyou","https://d…

【Python环境配置-Step1】PyCharm 2024最新官网下载、安装教程

背景: 1、 步骤: 1、PyCharm 官网下载地址:https://www.jetbrains.com/pycharm/ 2、查看下图红框选中,下载社区版(免费) 3、(查看下图红框选中)这里选其他版本 4、这里我下载的…

用vite创建项目

一. vite vue2 1. 全局安装 create-vite npm install -g create-vite 2. 创建项目 进入你想要创建项目的文件夹下 打开 CMD 用 JavaScript create-vite my-vue2-project --template vue 若用 TypeScript 则 create-vite my-vue2-project --template vue-ts 这里的 …

FBX福币交易所A股三大指数小幅低开 稀土永磁板块回调

查查配分析11月5日电 周二,A股三大指数小幅低开。沪指开盘跌0.10%报3306.81点,深证成指开盘跌0.09%报10653.20点,创业板指开盘跌0.05%报2184.90点。 FBX福币凭借用户友好的界面和对透明度的承诺,迅速在加密货币市场中崭露头角,成为广大用户信赖的平台。 来源:同花顺iFinD 盘面…

LeetCode总结-链表

一、遍历链表 1290.二进制链表转整数 2058.找出临界点之间的最小和最大距离 2181.合并零之间的节点 二、删除节点 问:为什么没有修改 dummy,但 dummy.next 却是新链表的头节点?如果删除了 head,那么最后返回的是不是原链表的头…

腐蚀图像分割系统:前端交互展示

腐蚀图像分割系统源码&数据集分享 [yolov8-seg-C2f-DySnakeConv&yolov8-seg-LSKNet等50全套改进创新点发刊_一键训练教程_Web前端展示] 1.研究背景与意义 项目参考ILSVRC ImageNet Large Scale Visual Recognition Challenge 项目来源AAAI Global Al…

NIM 平台生成式 AI-demo

需要python环境 官网注册:(后续调用模型需要秘钥key)Try NVIDIA NIM APIs 可以看到有多种模型: 官方案例 1.安装相关依赖: pip install langchain_nvidia_ai_endpoints langchain-community langchain-text-splitt…

欢迎使用Markdown编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

智慧医疗:AI如何改变传统医疗服务模式?

内容概要 在如今的医疗界,智慧医疗正如一阵旋风,呼啸而来,打破了传统的模式。这一变革的核心,毫无疑问是人工智能。想象一下,一个不需要排队候诊、甚至不需要出门的医生——这就是智能助手的非凡魅力!通过…

1.kubernetes作用及组件

容器管理集群名称叫做k8s 容器的编排工具:swarm,kubesphere,open shift,kubernetes【市场占比大】 一.kubernetes介绍 1.kubernetes是什么? 由谷歌公司开源的应用,基于go语言编写 简称k8s 2.kubernet…

【AcWing】算法基础课-动态规划

目录 1、闫式DP分析法 2、背包问题 2.1 01背包问题 朴素版本 优化版本 2.2 完全背包问题 朴素版本 优化版本 2.3 多重背包问题 朴素版本 二进制优化 2.4 分组背包问题 3、线性DP 3.1 数字三角形 3.2 最长上升子序列 3.3 最长公共子序列 4、区间DP 5、数位统计…

白天用的投影仪哪款好?掌握这个亮度参数谁敢忽悠你

人们追求松弛人生的同时,也着眼于高品质的家庭娱乐体验,高端家用投影仪以其大屏幕的视觉冲击力和便捷的移动性,应运成为众多家庭客厅、卧室的新宠。而在挑选家用投影仪时,亮度作为衡量其性能的重要指标之一,直接影响着…

七牛云OSS的使用

图片上传 一、七牛云oss介绍 1.1 图片存储介绍 在实际开发中,我们会有很多处理不同功能的服务器。例如: 应用服务器:负责部署我们的应用 数据库服务器:运行我们的数据库 文件服务器:负责存储用户上传文件的服务器…

重新构想定性数据分析:使用 NVivo 15 实现 AI、反思和备忘录

NVivo 是研究出版物中引用最多的定性数据分析软件 (QDA 软件),使用 NVivo v15 最新主要版本从定性和混合方法数据中发现更多信息,融合 Lumivero AI Assistant 更快地识别主题、运行高级查询和发现基于证据的见解,让您在更短的时间内获得严谨的研究结果。…

C++【string的模拟实现】

在前文我们讲解了string类接口使用(C【string类的使用】(上),C【string类的使用】(下)),本片文章就来模拟实现string类。 注:本文实现的是string的部分重点内容,目的是为了更好的了解string&…

zabbix安装配置与使用

zabbix Zabbix的工作原理如下: 监控部分: Zabbix Agent安装在各个需要监控的主机上,它以主配置的时间间隔(默认60s)收集主机各项指标数据,如CPU占用率、内存使用情况等。 通讯部分: Agent会把收集的数据通过安全通道(默认10051端口)发送到Zabbix Server。Server会存储这些数…