当前位置: 首页 > 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.jsqmd.com/news/35192/

相关文章:

  • 哥德尔不完备定理,其实为哥德尔不结束定理
  • 一个挺好用的SLM,ARPA格式
  • 程序员的第二成长曲线:从技术深度到认知广度
  • 实用指南:如何在 Linux_Ubuntu 上安装 Qt 5:详细教程
  • *题解:P2824 [HEOI2016/TJOI2016] 排序
  • 事务方法失效情况
  • Nginx是干嘛用的?nginx服务器配置
  • 2025年疏浚挖泥船实力厂家权威推荐榜单:绞吸清淤船/河道清淤船/清淤挖泥船源头厂家精选
  • 开源 C++ QT QML 开发(十三)多线程 - 实践
  • PyCharm 配置 PySide6
  • 《密码系统设计》第十周预习
  • 从容器到云原生:开发者需要掌握的核心思维
  • 从零开始学Flink:实时流处理实战 - 教程
  • 【STM32方案开源】基于STM32的智能语音台灯框架
  • 2025年实验室全钢通风橱订制厂家权威推荐榜单:实验室全钢排风柜/全钢结构步入式通风柜/全钢台式通风柜源头厂家精选
  • flask: 对Flask-SQLAlchemy查询得到的数据遍历处理
  • go 工作区(workspace)模式
  • # [NOIP 2016 提高组] 天天爱跑步 题解
  • 2025年搓管机全套管实力厂家权威推荐榜单:旋挖全套管/全回转钻机全套管/全回转全套管源头厂家精选
  • jmter题目
  • 提高组数学:扩展欧几里得
  • 2025广州人力资源服务推荐榜:精典人才领衔,派遣/外包靠谱公司精选3家
  • 51汇编--外部中断
  • 51汇编--定时器与计数器
  • 2025年杭州工厂外贸代运营公司权威推荐榜单:海外社媒推广/海外社媒营销/外贸推广源头公司精选
  • 51汇编--数码管显示
  • 深入解析:Isaac Lab 2.3深度解析:全身控制与增强遥操作如何重塑机器人学习
  • 51汇编--串口通信
  • 51-OLED显示代码
  • 新定义RD8T36P48点亮LED--汇编