MySQL的hash索引

news2025/2/2 16:04:02

 MySQL有B+Tree 索引及Hash索引等索引类型,B+Tree索引类型是MySQL采用最多的索引类型。Hash索引使用场景比较有限,文章将从Hash索引的底层结构出发,来分析Hash索引的利与弊。

1 hash数据结构

hash数据结构由键、哈希函数及哈希表组成。

:可以是任何字符串或整数,作为哈希函数的输入。

哈希函数:接收输入键并返回值,该值为哈希表的数组元素的索引。

哈希表:以关联方式将数据存储在数组中,其中每个数据值都有自己的唯一索引。

1.1 为什么需要哈希数据结构

我们可以用数组来存储数据,但是在进行数据检索时,需要一个个检索,时间复杂度为O(n),我们通过哈希数据结构,可以将复杂度缩短为O(1)。

1.2 哈希函数

唯一性

能生成唯一的哈希值。

固定性

生成的哈希值长度是固定的。

不可逆性

一种单向函数,无法从哈希值推导出原始输入。

确定性

给定相同的输入,哈希函数总能生成相同的哈希值。

散列性

输出值看起来是随机的,并且即使输入值只有一点微小的变化,映射出来的哈希值也截然不同。

表 哈希函数的特点

哈希函数主要有以下作用:

  1. 具有极强的错误检测能力,输入有很小的不同,输出将会有很大的不同。
  2. 数据完整性验证,验证数据在传输或存储过程是否被篡改。当数据被传输或存储时,将原始数据进行哈希求值。然后将哈希值与接收到的数据的哈希值比较,如果两个哈希值不同,则说明数据已被篡改。
  3. 密码存储。
  4. 哈希表。

哈希函数性能从以下方面来评价:

  1. 高效可计算。
  2. 均匀地分布键。
  3. 尽量减少碰撞。
  4. 具有较低的负载系数(项目数/表的大小),较高的值会减少空间开销哎,但会增加查找成本。

1.2.1 极简的哈希函数-MOD

哈希值 = 键值 MOD X; 即取键值除以X的余数。X最好是素数,这样可以确保哈希值分布更均匀。

比如有键值:2,5,7,9,11。X取值为7.则对应的哈希值分别为:2,5,0,2,4。

这种函数计算键值速度快,但是X取值需要特别的考虑。

1.3 碰撞

不同的键值可能产生相同的哈希值(比如上面的键值2和9),这种情况称为碰撞。在哈希表中,面对这种情况该如何存储值。有两种方案:1)链接法;2)开放寻址。

1.3.1 链接法

发生碰撞时,在对应的哈希表数组位置建立个链式结构,将值分别插入到链式结构中。

图 链接法示意图

1.3.2 开放寻址

所有原始都存储在哈希表本身中,每个哈希表数组元素包含一条记录或NULL。查找元素时,会逐个检查表槽,直到找到所需的元素或者明确该元素不在表中。

线性探测

  1. 根据哈希函数计算哈希值为k;
  2. 检查hashTable[k]是否为空,为空则直接存储。
  3. 不为空,使用 k= (k+1)%size,检查新k的位置是否为空,为空则直接存储。
  4. 不为空,则重复第3步,直到找到可存储的空间。

二次探测

计算原始哈希值,并添加任意二次多项式的连续值,直到找到空槽。

双重哈希

利用两个函数f1及f2,先用f1计算哈希值,如果位置不为空,则借助f2来计算新的哈希值。 (f1(k) + i * f2(k))%n,其中n表示哈希表大小,k是键值,i是碰撞次数。

表 开放寻址的三种算法

2 MySQL的hash索引

MySQL的hash索引采用的是链式哈希表结构。是基于内存的支持,增删改查的时间复杂度都是O(1)。它只适合等值查找,其他查找时,发挥不了作用。

因为hash结构及其基于内存的缘故,hash索引有以下的缺陷:

  1. 绝对部分数据存放在磁盘,hash索引无法减少磁盘I/O次数,其只适用于小数据量的等值查询。
  2. 不同的键值经过hash计算后,最后的位置非常不确定,没有任何顺序。所以不适合范围、模糊查找及排序。
  3. 一旦哈希表扩容,就会导致所有的索引值重新计算存储位置,效率低。

2.1 自适应哈希索引

看似哈希索引百无一用,但是在MySQL中,有一种哈希索引发挥着关键的作用:自适应哈希索引。

索引根据存储形式分为聚集索引及二级索引。当我们使用二级索引进行查询时,MySQL会根据二级索引查询到的主键值,进行回表查询(即再根据主键值来获取该条数据)。频繁的回表查询将会降低查询效率。

自适应哈希索引,是为了避免频繁回表而创建的。MySQL会判断哪些二级索引值是热查询,为它们建立自适应索引,查询时,根据这个索引直接获取数据,而无需通过主键再获取数据。

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

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

相关文章

Hive文件存储与压缩

压缩和存储 1、 Hadoop压缩配置 1) MR支持的压缩编码 压缩格式工具算法文件扩展名是否可切分DEFAULT无DEFAULT.deflate否GzipgzipDEFAULT.gz否bzip2bzip2bzip2.bz2是LZOlzopLZO.lzo否LZ4无LZ4.lz4否Snappy无Snappy.snappy否 为了支持多种压缩/解压缩算法,Hadoop…

acwing linux 第七讲 环境变量、管道、常用命令、附录

文章目录 管道 概念 要点 举例 环境变量 查看 修改 常用环境变量 常用命令 系统状况 文件权限 文件检索 查看文件内容 用户相关 其他工具 安装软件 附录 Linux权限 本节课讲解的是管道,环境变量,以及常用命令 管道 概念 管道类似文…

MD5的实现与“破解”

MD5的实现与“破解” 文章目录 MD5的实现与“破解”一、 概述二、 MD5简单介绍三、 MD5的实现四、 MD5的“破解”五、MD5的“破解”方法1. 暴力破解:穷举法&字典法2. 时间和空间的折中:哈希链表法&彩虹表法2.1. 哈希链表法的过程2.2. 哈希链表可…

C# WPF上位机开发(多线程中锁的使用)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 多线程编程一般都会涉及到锁的时候,很多人可能觉得很意外,为什么会需要这么一个锁。本质上,这主要还是因为多线…

深度学习中的损失函数

1 损失函数概述 大多数深度学习算法都会涉及某种形式的优化,所谓优化指的是改变以最小化或最大化某个函数 的任务,我们通常以最小化指代大多数最优化问题。 在机器学习中,损失函数是代价函数的一部分,而代价函数是目标函数的一种…

python脚本传参

sys.argvargparse 第一种:argparse 简单使用: import argparse # 创建一个参数解析实例 parser argparse.ArgumentParser(descriptionParameters) # 添加参数解析 parser.add_argument(--training_epoch, typeint, default3000) parser.add_argument(…

Layui 下拉select多选实现

1. html <div id"mo_deptment"></div> 2.引用 <script src"~/layuiadmin/layui/xm-select.js"></script>3.设置全局变量存储控件 var mo_deptmentSelect; 4.layui.use 中初始化 4.1 列表数据 var mo_deptmentdata [ …

Ubuntu 常用命令之 mkfs 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 mkfs 是在 Linux 和其他 Unix-like 系统中用于创建文件系统的命令。在 Ubuntu 系统中&#xff0c;mkfs 命令也是用于创建文件系统的。mkfs 是一个包装器&#xff0c;它会根据用户指定的文件系统类型调用相应的程序。 mkfs 命令的…

第11章 GUI Page403~405 步骤三 设置滚动范围

运行效果&#xff1a; 源代码&#xff1a; /**************************************************************** Name: wxMyPainterApp.h* Purpose: Defines Application Class* Author: yanzhenxi (3065598272qq.com)* Created: 2023-12-21* Copyright: yanzhen…

【C语言】记录一次自己犯下的低级错误 o(╯□╰)o(局部数组与指针数组的传参、赋值)

在这里分享一下本人犯下的低级错误&#xff0c;希望大家别掉同样的坑 o(╥﹏╥)o 文章目录 事情原委错误分析及解救办法错误一&#xff1a; 使用局部数组arr并将其作为返回值解决方法&#xff1a;使用动态内存分配来创建数组&#xff0c;并在函数结束前手动释放内存。 错误二&…

Mac查询本机ip地址

Mac系统版本和网络配置不同&#xff0c;可能会有一些细微差别。 一、 使用系统偏好设置 1、点击屏幕左上角的Apple图标&#xff0c;选择“系统偏好设置”。 2、点击“网络”。 3、 在左侧选择当前连接的网络&#xff08;如Wi-Fi或以太网&#xff09;&#xff0c;在右侧界面&a…

在Linux系统中安装MySQL数据库

目录 一、MySQL简介 二、MySQL安装步骤 1、下载MySQL的YUM仓库文件 2、安装MySQL源 3、解决密钥异常问题 4、安装MySQL服务器 5、开启MySQL服务 6、查看MySQL服务器中root用户的初始密码 7、使用初始密码登录MySQL服务器 8、修改root用户登录MySQL服务器的密码 三、…

两个图片完美融合 泊松编辑

一、效果惊人 二、步骤 下载安装 https://github.com/Trinkle23897/Fast-Poisson-Image-Editing.git 执行 test 目录下的 python data.py下载数据 执行测试&#xff0c;可以看到效果了 $ fpie -s test1_src.jpg -m test1_mask.jpg -t test1_tgt.jpg -o result1.jpg -h1 -…

Python匹配文件模块的实战技巧

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 在Python中&#xff0c;文件匹配是许多应用中常见的需求&#xff0c;例如文件管理、数据处理等。本文将深入探讨Python中用于文件匹配的模块&#xff0c;包括glob、fnmatch和os.path等&#xff0c;通过丰富的示例…

代码随想录算法训练营Day7 | 344.反转字符串、541.反转字符串||、替换数字、151.反转字符串中的单词、右旋字符串

LeetCode 344 反转字符串 本题思路&#xff1a;反转字符串比较简单&#xff0c;定义两个指针&#xff0c;一个 i 0, 一个 j s.length-1。然后定义一个临时变量 tmp&#xff0c;进行交换 s[i] 和 s[j]。 class Solution {public void reverseString(char[] s) {int i 0;int …

vitepress项目使用github的action自动部署到github-pages中,理论上可以通用所有

使用github的action自动部署到github-pages中 创建部署的deploy.yml文件&#xff0c;在项目的根目录下面 .github\workflows\deploy.yml 完整的代码&#xff1a;使用的是pnpm进行依赖安装。 name: 部署VitePresson:push:branches:- docs # 这段是在推送到 docs 分支时触发该…

学鸿蒙开发的过程,差点要了我的命!

我真的好想感慨一下&#xff0c;这个世界真的给计算机应届生留活路了吗&#xff1f; 看着周围的同学&#xff0c;打算搞前端、JAVA、C、C的&#xff0c;一个两个去跑去应聘。你以为是00后整治职场&#xff1f; 真相是主打一个卑微&#xff1a;现阶段以学习为主&#xff08;工资…

使用宝塔面板部署前端项目到服务器

目录 文章目录 前言 一、第一步&#xff1a;创建文件夹 二、第二步&#xff1a;部署前端项目 三、第三步&#xff1a;打开防火墙 文章目录 前言第一步&#xff1a;创建文件夹第二步&#xff1a;部署前端项目第三步&#xff1a;打开防火墙总结 前言 在此之前&#xff0c;我…

Vue3选项式API和组合式API详解

前言 相信学习Vue3的人中大多数都是之前使用Vue2开发的&#xff0c;当拿到一个Vue3项目时就接触到了组合式api&#xff0c;但对于组合式api不了解的人第一眼看上去会觉得一头雾水。&#xff1a;“什么玩意&#xff0c;乱七八糟的&#xff0c;选项式api多好&#xff0c;方法变量…

反序列化版本漏洞

laravel5.7反序列化漏洞 <?phpnamespace Illuminate\Foundation\Testing {class PendingCommand{public $test;protected $app;protected $command;protected $parameters;public function __construct($test, $app, $command, $parameters){$this->test $test; …