MySQL索引

本文参考自聚集索引与非聚集索引的总结 以及 姜承尧的《MySQL技术内幕–InnoDB存存储引擎》

MySQL 索引详解

在开始介绍前,我们先整理一下 MySQL 的索引:

聚集索引、非聚集索引(普通索引,组合索引,唯一索引)、倒排索引(用于全文检索,也称全文索引)、哈希索引

其中,聚集索引和非聚集索引的存储结构都是 B+ 树结构,全文检索的倒排索引则主要是一张辅助表。

需要注意的是:B+ 树索引不能找到一个给定键值的具体行,只能找到被查找数据行所在的页,然后数据库通过把页读入到内存,再在内存中进行查找,最后得到要查找的数据。

我们通过看图来理解:

数据表:

NONAMEAGE
1AA24
2AB19
3AC27
4BB36
5BA44
6BC24
7CC19
8CB27
9CA36
10DD19
11DA27
12DB36

 

聚集索引

 
聚集索引其实就是主键索引,创建表时指定了主键,就会默认创建一个聚集索引;如果没有指定主键,就会自动创建一个隐藏的列作为表的聚集索引。

KR2EgH.md.png

非叶子节点中,有一个 key 和一个指向下一级节点的页地址,其中 key 一般就是主键。叶子节点中,则是一页完整的数据行,相邻叶子之间会有一个指针使之相连。
 

非聚集索引

KR44vF.md.png

非聚集索引的叶子节点,不会存储整行数据,只会存储一个 key 和一个指向该 key 对应的整行数据。

也就是说,非聚集索引对数据的物理存储结构没有影响。(最下面的数据存放不一定是这个顺序)

非聚集索引分类:

  • 普通索引:就是非聚集索引,可以在任意一列上建立。
  • 唯一索引:跟普通索引相似,但要求该列的值不重复。
  • 组合索引:在多个数据列上建立索引,下面是一个组合索引的示意图,在a,b列上建立了组合索引:

KWvbDI.md.png

注:以上图为例,进行数据查找时,对 ab 同时选择,或只对 a 进行选择时,会用到上面这个索引,但如果只对 b 进行选择,则不会使用这个组合索引。因为索引中只对 a,ab 进行了排序,没有对 b 进行排序,因此只对 b 进行筛选时无法使用上面的组合索引。(也称为最左前缀

覆盖索引:从非聚集索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。非聚集索引不包含整行记录的所有信息,故其大小要远小于聚集索引,因此可以减少大量的 IO 操作。

 

全文索引

现在我们有如下的数据表 document,并在 Text 列上建立全文索引

CREATE FULLTEXT INDEX idx_text ON document(Text)

数据表:

KfpfLd.md.png

接下来数据库会隐式的建立如下的辅助表,该辅助表存放在磁盘中:

KhOd4U.md.png

第三列存的是该单词出现的位置,第一个数字是 DocumentId,第二个数字是它在 Text 的第几个单词。

在 InnoDB 存储引擎的全文索引中,还有一个重要概念,即 FTS Index Cache(全文检索索引缓存),它能提高全文检索的速度。

它是一个红黑树结构,其根据(word,ilist)进行排序,ilist就是(DocumentId,Position),即辅助表中的 Documents 的数据对。

 

哈希索引

哈希索引的相关结构和算法就不详细展开,其中哈希冲突的解决方法是链地址法。由于哈希算法的特性,我们可以知道,对于字典类型的查找使用哈希索引会非常快速,但对于范围查找它就无能为力了。

哈希索引是数据库自身创建并使用的,我们无法对其进行干预,只能通过参数 innodb_adaptive_hash_index 来禁用或者启动开启,默认为开启。

资源下载链接为: https://pan.quark.cn/s/f989b9092fc5 今天给大家分享一个关于C#自定义字符串替换方法的实例,希望能对大家有所帮助。具体介绍如下: 之前我遇到了一个算法题,题目要求将一个字符串中的某些片段替换为指定的新字符串片段。例如,对于源字符串“abcdeabcdfbcdefg”,需要将其中的“cde”替换为“12345”,最终得到的结果字符串是“ab12345abcdfb12345fg”,即从“abcdeabcdfbcdefg”变为“ab12345abcdfb12345fg”。 经过分析,我发现不能直接使用C#自带的string.Replace方法来实现这个功能。于是,我决定自定义一个方法来完成这个任务。这个方法的参数包括:原始字符串originalString、需要被替换的字符串片段strToBeReplaced以及用于替换的新字符串片段newString。 在实现过程中,我首先遍历原始字符串,查找需要被替换的字符串片段strToBeReplaced出现的位置。找到后,就将其替换为新字符串片段newString。需要注意的是,在替换过程中,要确保替换操作不会影响后续的查找和替换,避免遗漏或重复替换的情况发生。 以下是实现代码的大概逻辑: 初始化一个空的字符串result,用于存储最终替换后的结果。 使用IndexOf方法在原始字符串中查找strToBeReplaced的位置。 如果找到了,就将originalString中从开头到strToBeReplaced出现位置之前的部分,以及newString拼接到result中,然后将originalString的查找范围更新为strToBeReplaced之后的部分。 如果没有找到,就直接将剩余的originalString拼接到result中。 重复上述步骤,直到originalStr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值