数据库总结(一)--数据库中的索引技术——哈希索引

原文链接

目录

数据库中的索引技术——哈希索引


数据库中的索引技术——哈希索引

1、哈希索引

哈希索引(hash index)基于哈希表实现,只有精确匹配索引所有列的查询才有效。对于每一行数据,存储引擎都会对所有的索引列计算一个哈希码(hash code),哈希码是一个较小的值,并且不同键值的行计算出来的哈希码也不一样。哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针。

对于hash相同的,采用链表的方式解决冲突。类似于hashmap。因为索引的结构是十分紧凑的,所以hash索引的查询很快。

举例:
这里写图片描述

hash索引的限制:

  • 哈希索引只包含哈希值和行指针,而不存储字段值,所以不能使用索引中的值来避免读取行。
  • 哈希索引数据并不是按照索引值顺序存储的,所以也就无法用于排序。
  • 哈希索引也不支持部分索引列匹配查找,因为哈希索引始终是使用索引列的全部内容来计算哈希值的。
  • 哈希索引只支持等值比较查询,包括=、IN()、<>(注意<>和<=>是不同的操作)。也不支持任何范围查询,例如WHERE price>100。
  • 访问哈希索引的数据非常快,除非有很多哈希冲突(不同的索引列值却有相同的哈希值)。当出现哈希冲突的时候,存储引擎必须遍历链表中所有的行指针,逐行进行比较,直到找到所有符合条件的行。
  • 如果哈希冲突很多的话,一些索引维护操作的代价也会很高。例如,如果在某个选择性很低(哈希冲突很多)的列上建立哈希索引,那么当从表中删除一行时,存储引擎需要遍历对应哈希值的链表中的每一行,找到并删除对应行的引用,冲突越多,代价越大。

2、自适应哈希

在Mysql中InnoDB引擎有一个特殊的功能叫做自适应哈希索引,它会在内存中基于B-Tree索引的基础上面创建一个哈希索引,这让B-Tree索引具备了一些哈希索引的优点。

创建自定义哈希索引:

如果存储引擎不支持哈希索引,则可以模拟像InnoDB一样创建哈希索引,这可以享受一些哈希索引的便利,例如只需要很小的索引就可以为超长的键创建索引。
思路:在B-Tree基础上创建一个伪哈希索引。这和真正的哈希索引不是一回事,因为还是使用B-Tree进行查找,但是它使用哈希值而不是键本身进行索引查找。你需要做的就是在查询的WHERE子句中手动指定使用哈希函数。
这里写图片描述
这里写图片描述

### 数据库中 B+ 树索引哈希索引的区别 #### 1. 结构差异 B+树索引采用种多路平衡查找树的数据结构,所有的叶子节点都位于同层,并且这些节点之间存在链表连接。这种设计使得B+树不仅支持快速的等值查询,还非常适合范围查询操作[^1]。 相比之下,哈希索引则是利用散列函数将记录的关键字映射到特定位置上形成的索引方式。由于其工作原理决定了只有当键完全相等时才能定位到对应的行数据,因此不适用于范围扫描或部分匹配的情况[^5]。 #### 2. 查询效率对比 对于单条记录的精准查找而言,如果不存在大量冲突(即多个不同关键字被映射到了同个地址),那么理论上讲哈希索引可以达到O(1)的时间复杂度,而B+树则通常为O(log n)[^4]。然而,在实际应用环境中,考虑到可能存在的哈希碰撞以及随之带来的额外处理开销,两者的性能差距往往并没有理论分析得那么明显。 另外值得注意的是,随着表内数据量的增长,维护个高效的哈希索引所需的空间也会相应增加,这可能导致内存占用过高甚至溢出等问题的发生;相反地,B+树能够较好地适应大规模数据集并保持相对稳定的访问速度[^3]。 #### 3. 更新成本考量 每当向数据库插入新元组或者删除已有元组时,都需要同步更新相应的索引信息。就这点来说,B+树相较于哈希索引拥有更低廉的成本——前者仅需调整局部子树即可完成任务,后者却有可能因重新计算整个哈希表而导致较高的时间消耗[^2]。 ### 应用场景推荐 - **适合使用B+树索引的情形** - 需要频繁执行区间查询、排序输出的操作; - 表结构经常变动,如增删改查频率较高; - 关心整体读写性能而非单纯追求某类特殊查询的速度优势。 - **更适合部署哈希索引的情境** - 主要是针对唯性约束字段实施高效检索; - 当前业务逻辑主要围绕着固定模式下的精确匹配展开; - 对象集合规模较小且不易发生变化,从而减少重建索引所带来的资源浪费风险。 ```sql -- 创建带有B+树索引的表格实例 CREATE TABLE employees ( id INT NOT NULL, name VARCHAR(50), department_id INT, PRIMARY KEY (id), -- 默认创建B+树索引 INDEX idx_department (department_id) USING BTREE -- 显式指定使用B+树作为索引类型 ); -- 构建哈希索引的例子 CREATE TABLE user_accounts ( account_number CHAR(8) NOT NULL, balance DECIMAL(10, 2), PRIMARY KEY (account_number) USING HASH -- 使用哈希算法构建主键索引 ); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值