当前位置: 首页 > news >正文

数据库存储中的哈希表和B+树

哈希表

哈希表是一种通过哈希函数将键直接映射到存储位置的数据结构,其核心目标是实现​​平均时间复杂度为 O(1)​​ 的等值查询。

核心原理

  1. ​哈希函数​​:接收一个键作为输入,返回一个整数值(哈希值)。一个好的哈希函数应该能将键均匀地分布到整个地址空间。

  2. ​哈希桶​​:哈希值对应一个存储单元,通常称为“桶”。一个桶可以包含一个或多个数据项。

  3. ​解决冲突​​:当两个不同的键经过哈希函数计算后得到相同的哈希值(即发生哈希冲突)时,需要解决。常见方法有:

    • ​链地址法​​:每个桶维护一个链表,所有映射到该桶的键值对都存储在这个链表中。这是最常用的方法。

    • ​开放定址法​​:当发生冲突时,按照某种探测序列(如线性探测、平方探测)寻找下一个空闲的桶。

在数据库中的应用

哈希表在数据库中最典型的应用是​​哈希索引​​。例如,MySQL的Memory存储引擎就支持哈希索引。

  • ​存储方式​​:对于一张表的某一列(如user_id)创建哈希索引。

    1. 数据库会为这一列的值(键)计算哈希值。

    2. 根据哈希值找到对应的哈希桶。

    3. 将完整的​​行数据指针​​ 与该键一起存入桶内的链表中。

  • ​查询过程​​:当执行 WHERE user_id = 123这样的等值查询时:

    1. 对 123计算哈希值。

    2. 定位到对应的哈希桶。

    3. 遍历桶内的链表,比较键的值,找到匹配的 user_id = 123的记录。

    4. 通过存储的行数据指针,快速读取到完整的行数据。

优点

  • ​极高的等值查询效率​​:在理想情况下(无冲突或冲突很少),一次查询即可定位数据,速度极快。

  • ​插入和删除效率高​​:同样基于哈希定位,插入和删除操作也非常高效。

缺点

  • ​无法支持范围查询​​:这是哈希索引最致命的缺点。由于哈希函数打乱了键的原始顺序,你无法高效地进行 WHERE user_id > 100 AND user_id < 200这样的查询。数据库只能进行全表扫描。

  • ​无法利用索引进行排序​​:ORDER BY子句无法使用哈希索引,原因同样是数据无序。

  • ​不支持最左前缀匹配​​:对于复合索引(多列索引),哈希索引必须使用所有列进行查询才能生效。

  • ​性能受数据分布影响大​​:如果哈希函数选择不当,导致大量数据聚集在少数桶中,会使链表过长,查询效率退化为 O(n)。

​适用场景​​:主要用于等值查询(=, IN)密集型、且几乎没有范围查询和排序需求的场景,例如缓存(如Redis的Hash结构)、数据字典等。


B+树

B+树是B树的一种变体,它是​​为磁盘或其他直接存取的辅助存储设备而设计​​的一种平衡查找树。目前几乎所有关系型数据库(如MySQL的InnoDB、PostgreSQL)的主键索引都采用B+树。

核心特性与结构

一棵B+树具有以下关键特征:

  1. ​多路平衡查找树​​:一个节点可以有多个子节点(远多于二叉树的2个),这大大降低了树的高度,从而减少了磁盘I/O次数。

  2. ​所有数据都存储在叶子节点​​:这是与B树的主要区别。内部节点(非叶子节点)只充当导航作用,存放键和指向子节点的指针。

  3. ​叶子节点通过指针顺序链接​​:所有叶子节点被一个双向链表串联起来,这使得范围查询变得异常高效。

  4. ​节点大小通常设置为磁盘页的大小(如4KB, 16KB)​​:这样一次磁盘I/O就可以读取一个完整的节点,极大提升了效率。

一个典型的B+树结构如下:

  • ​根节点​​:树的顶端。

  • ​内部节点​​:介于根节点和叶子节点之间。

  • ​叶子节点​​:树的最底层,存储了​​所有的键值对​​。其中,键是索引列的值,而“值”根据索引类型不同而不同:

    • ​在主键索引中​​:值就是完整的行数据(InnoDB的聚簇索引)。

    • ​在非主键索引中​​:值是对应主键的值。

在数据库中的应用

以InnoDB引擎为例:

  • ​查询过程​​:当执行 WHERE id = 123时,从根节点开始,通过节点内的键值进行二分查找,找到下一个子节点,直到最终在叶子节点找到目标记录。

  • ​范围查询过程​​:当执行 WHERE id > 100 AND id < 200时,首先通过一次查找定位到 id=100所在的叶子节点,然后利用叶子节点间的顺序指针,向后顺序遍历即可,无需回溯到上层节点。

优点

  • ​出色的范围查询和排序性能​​:得益于叶子节点的顺序链表。

  • ​稳定的查询性能​​:作为一棵平衡树,所有查询操作的时间复杂度都是 ​​O(log n)​​,非常稳定,不会出现性能突降。

  • ​支持最左前缀匹配​​:对于复合索引(如 index (last_name, first_name)),可以高效查询 WHERE last_name = ‘Smith’

  • ​数据全量遍历高效​​:只需要遍历叶子节点的链表即可,无需遍历整棵树。

缺点

  • ​相对于哈希表,等值查询稍慢​​:平均需要 O(log n) 次磁盘I/O,而哈希表在理想情况下只需 O(1) 次。

  • ​结构更复杂​​:插入和删除操作可能涉及节点的分裂与合并,以维持平衡。

​适用场景​​:B+树是​​通用型​​的索引结构,适用于绝大多数的数据库操作,包括等值查询、范围查询、排序、分组等。是关系型数据库的默认和标准选择。


一个形象的比喻

  • ​哈希表就像一本电话簿的“姓名索引”​​:如果你知道要找“张三”,你可以直接翻到“Z”开头的部分快速查找。但如果你想找“所有姓张的人”,用这种方法就很麻烦,需要把“张”开头的名字都看一遍。

  • ​B+树就像一本完整的、按字母顺序排列的电话簿​​:找“张三”需要先按字母顺序找到“Z”,再找“Zhang”,最后找到“张三”,比直接翻到“Z”部分稍慢一点。但如果你想找“所有姓张的人”,你只需要找到“张”开始的页面,然后一页一页顺序翻下去即可,效率极高。

结论

在数据库存储中,​​B+树是绝对的主流​​,因为它完美地契合了磁盘的存取特性和数据库常见的查询模式(混合着等值查询和范围查询)。而​​哈希表则是一种在特定场景下性能极佳的补充​​。

http://www.dtcms.com/a/461793.html

相关文章:

  • 绵阳网站推广优化和田知名网站建设企业
  • MQTT 协议应用指导
  • 蘑菇采摘公司:Mycionics
  • billfish本地资源库占内存吗
  • 深度残差网络(ResNet)
  • 专题五:位运算~
  • C++语言编程规范-资源分配和释放
  • 影视广告网站重庆网站建设制作
  • Hadess入门到实战(9) - 如何管理Composer(PHP)制品
  • 如何设计公司官网站苏宁易购网站风格
  • wx小程序扫码入口方式
  • Agent 开发设计模式(Agentic Design Patterns )第 1 章:提示词链
  • asp美食网站源码天津网站推广
  • 图像处理踩坑:浮点数误差导致的缩放尺寸异常与解决办法
  • Android Studio Meerkat 打开flutter项目没有自动选中main.dart configuration
  • OpenTiny TinyEngine 基础知识
  • 大模型-旋转位置编码(Rotary Positional Embedding)
  • 如何减小ES和mysql的同步时间差
  • this.$router.push 与 this.$router.replace 跳转的区别
  • 网站域名到期时间查询网站建设蛋蛋28
  • 建设网站选题应遵循的规则网站网页打开的速度什么决定的
  • 【Servlet】使用idea2023创建Servlet JavaWeb
  • 异步串口通信和逻辑分析仪
  • 中微电力建设公司网站建设人行官方网站
  • crew AI笔记[9] - 运用crew AI框架构建实战级agent项目
  • 12.MySQL使用C连接和连接池
  • Spring前置准备(八)——ConfigurableApplicationContext和DefaultListableBeanFactory的区别
  • 鸿蒙开发5--鸿蒙页面导航(声明式导航Navigation组件)
  • sql题目练习——单表查询
  • html怎么做成网站多软件网站下载安装