07-数据库学习笔记(数据库哈希表)

一.哈希表基础

1.核心

哈希表 = 数组 + 哈希函数 + 冲突处理

目标:理想情况下 O (1) 时间完成查找、插入、删除。

  • 普通数组:按下标访问很快,但不知道下标就只能遍历 O (n)。
  • 哈希表:给任意「关键字 key」算出一个数组下标,直接定位存储位置。

2.哈希函数

输入:任意长度关键字 key(整数、字符串、对象等)

输出:固定范围的整数,称为哈希值

核心目标:把分布杂乱的 key,尽可能均匀散布到各个下标,减少哈希冲突。

要求: 计算快;输出范围落在数组下标区间 0, size-1;尽量让 key 均匀分布,减少碰撞。

3.哈希表优缺点

优点 :精准点查询、插入、删除速度极快,平均常数级耗时;结构简单、内存开销可控;广泛用于数据库哈希连接、临时查询结构、元数据表、哈希索引。

缺点:数据无序,无法支持范围查询、前缀匹配、排序;存在哈希冲突风险,最坏性能退化至O(n);静态哈希表扩容成本极高。

二.静态哈希方案

(静态哈希指哈希表容量初始化后固定不变,无法动态伸缩,若存储空间不足,必须整体重建整张哈希表。静态哈希存在三大理想化假设:数据总量已知且固定、所有键值唯一、哈希函数无冲突,在真实数据库场景均不成立,因此衍生两种主流实现:线性探测哈希、布谷鸟哈希。)

1.线性探测哈希

(1)核心逻辑

基于固定大小的环形数组槽位,寻址公式:hash(key) % N。key:要存储查找的关键字。hash:哈希函数,作用是把任意长度的Key,转化成一个整数哈希值。N:哈希表的固定大小(也就是槽位的总数,比如数组长度为10,则N=10)

  • 插入: 键值哈希命中槽位,若槽位被占用,则向后线性遍历后续槽位,循环寻址,直至找到空闲槽位存入数据;
  • 查询: 定位初始哈希槽位,向后线性扫描,匹配键值则返回数据,遇到空槽则判定数据不存在;
  • 删除: 禁止直接清空槽位,否则会中断后续探测链路,导致后续数据无法查询。

(2)墓碑标记

开放寻址哈希删除元素时,不能直接清空位置,否则切断探测链路导致后面的数据找不到;于是设立墓碑标记:代表这里曾经有数据,现在删了,查询路过时不要停下,继续往后搜寻。

缺点:

  • 墓碑不会自动消失
    反复增删,数组里墓碑越堆越多。每次查找都要跨过一堆墓碑,探测链条越来越长,性能持续下降。
    解决手段:定期重建哈希表,清除全部墓碑。
  • 墓碑不能当做空位给新车停放
    分两种实现策略:
    策略 1(保守):墓碑不允许直接存入新数据,只做通路;
    策略 2(优化):插入新元素时,可以覆盖墓碑位置,缩短探测链。

2.布谷鸟哈希

(1)技术背景

线性探测哈希的查询、删除性能不稳定,高负载下性能退化严重。为了解决该问题,布谷鸟哈希采用多哈希函数寻址机制,彻底缩短探测路径,保证查询、删除操作稳定高效,满足数据库对查询性能稳定的需求。

(2)核心逻辑

核心设计:为同一个键值提供多个哈希函数 ,映射出多个可选存储槽位。

  • 插入: 优先遍历多个哈希槽位,存入空闲槽位;若所有槽位均被占用,则随机驱逐已有数据,将被驱逐数据重新哈希寻址,循环迭代;若出现循环驱逐、无法收敛,则重建哈希表、扩容并更新哈希种子。
  • 查询/删除: 仅需要计算多个固定槽位,精准校验,无需线性遍历,因此可以稳定保证O(1)查询、删除复杂度。

三.动态哈希方案

(静态哈希最大缺陷为无法按需扩容,数据量增长后必须全量重建,IO与CPU开销极高。动态哈希技术的核心背景就是解决静态哈希扩容成本过高的问题,实现哈希表增量伸缩,无需全量重建,适配数据库数据持续增长的真实场景。包含链式哈希、可扩展哈希、线性哈希三种主流实现。)

1.链式哈希

(1)技术背景

开放寻址类静态哈希在高冲突场景性能极差,为了彻底解决哈希堆积问题,同时实现基础动态扩容能力,链式哈希应运而生,是最简单、最通用的动态哈希方案。

(2)核心逻辑

哈希表每个槽位不直接存储数据,而是存储桶链表指针。所有哈希到同一槽位的数据,全部追加至该槽位对应的桶链表中。

  • 插入: 计算槽位,将数据追加至对应链表尾部;
  • 查询: 定位槽位,遍历链表匹配目标键值;
  • 删除: 遍历链表删除对应节点,无需墓碑标记,直接删除数据即可。

(3)优缺点

优点 :彻底规避开放寻址的数据聚类问题;支持无限追加数据,天然适配动态数据增长;删除逻辑简单、无数据丢失风险。

缺点:链表指针存储带来额外内存开销;链表离散存储;链表过长时查询性能退化严重。

2.可扩展哈希

(1)技术背景

链式哈希会导致链表无限变长,性能持续退化。为了限制链表长度、实现精细化增量扩容,可扩展哈希优化链式哈希,通过桶分裂替代链表无限增长,平衡动态扩容与查询性能。

(2)核心逻辑

引入全局深度、局部深度 两个位计数,通过哈希值高位比特匹配桶地址:

1、全局深度:代表当前哈希表整体寻址比特位数,控制目录数组大小;

2、局部深度:单个桶的寻址比特位数;

3.线性哈希

(1)技术背景

可扩展哈希仅在桶溢出时分裂,扩容随机性强,容易出现部分桶数据堆积、负载不均衡。线性哈希为了实现均匀、有序、可控的增量扩容,引入分裂指针机制,统一管控扩容节奏。

(2)核心逻辑

核心是维护全局分裂指针 ,标记下一个待分裂的桶。

无论哪个桶出现数据溢出,系统都优先分裂指针指向的桶,而非溢出桶。同时维护新旧两套哈希函数,分裂后的桶使用新哈希函数重分布数据。指针遍历完所有桶后,完成一轮全局扩容,重置指针、废弃旧哈希函数。同时支持反向收缩,空闲桶过多时可缩容,节省存储空间。

相关推荐
喜欢的名字被抢了2 小时前
FastAPI 接入异步 PostgreSQL 完成任务 CRUD 与数据库迁移
数据库·postgresql·fastapi
Goodbye2 小时前
给 AI 装上记忆:基于 Milvus 向量数据库与 RAG 的智能日记系统实战
数据库
九皇叔叔2 小时前
RHEL 9.8 安装 Redis 8.8.1
数据库·redis·bootstrap
Python私教2 小时前
如意 Django CRM 容器化实战:后端、前端、数据库、Redis 的协同启动逻辑
前端·数据库·django
海兰3 小时前
【数据库】tdsql(MySQL )的事务隔离级别
android·数据库·mysql
小蒜学长3 小时前
“守望自然”招募志愿者环保行动网站的设计与实现(代码+数据库+LW)
java·数据库·spring boot·后端
灵析表格3 小时前
Excel连接MySQL的函数化革命:灵析表格MySQL函数族业务应用分析
数据库·mysql·adb·excel·wps·灵析表格·excel公式盒子
todoitbo3 小时前
把发票台账接进 Codex:KingbaseES MCP 的一次只读风险排查实践
数据库·oracle·codex·kingbasees·mcp
Navicat中国4 小时前
使用 Navicat 轻松生成数据库测试数据
数据库·数据