CMU 15-445 -- Hash Tables - 04

CMU 15-445 -- Hash Tables - 04

  • 引言
  • Hash Tables
    • Hash Functions
    • Hashing Scheme
    • 小结
  • Dynamic Hash Tables
    • Chained Hashing (链式哈希)
    • Extendible Hashing(可扩展哈希)
    • Linear Hashing(线性哈希)
  • 总结


引言

本系列为 CMU 15-445 Fall 2022 Database Systems 数据库系统 [卡内基梅隆] 课程重点知识点摘录,附加个人拙见,同样借助CMU 15-445课程内容来完成MIT 6.830 lab内容。


本节开始之前,先看一下目前课程的进度状态:
在这里插入图片描述
为了支持 DBMS 更高效地从 pages 中读取数据,DBMS 的设计者需要灵活运用一些数据结构及算法,其中对于 DBMS 最重要的两个是:

  • Hash Tables
  • Trees

它们可能被用在 DBMS 的多个地方,包括:

  • Internal Meta-data
  • Core Data Storage
  • Temporary Data Structures
  • Table Indexes

在做相关的设计决定时,通常需要考虑两个因素:

  • Data Organization:如何将这些数据结构合理地放入 memory/pages 中,以及为了支持更高效的访问,应当存储哪些信息
  • Concurrency:如何支持数据的并发访问

Hash Tables

Hash Table 主要分为两部分:

  • Hash Function:
    • How to map a large key space into a smaller domain
    • Trade-off between being fast vs. collision rate
  • Hashing Scheme:
    • How to handle key collisions after hashing
    • Trade-off between allocating a large hash table vs. additional instructions to find/insert keys

Hash Functions

由于 DBMS 内使用的 Hash Function 并不会暴露在外,因此没必要使用加密(cryptographic)哈希函数,我们希望它速度越快,collision rate 越低越好。目前各 DBMS 主要在用的 Hash Functions 包括:

  • MurmurHash (2008)
  • Google CityHash (2011)
  • Google FarmHash (2014)
  • CLHash (2016)

Hashing Scheme

  • Linear Probe Hashing (线性探测法) :就是在发生冲突的时候,找到最近的下一个空闲位置,将 item 插入。

当 keys 可能出现重复,但 value 不同时,有两种做法:

  • Separate Linked List(分离链表):这种方法使用链表来处理哈希表中冲突的情况。当发生冲突时,即多个键被映射到同一个哈希桶(存储位置),它们将被存储在一个链表中。每个节点包含键和对应的值。通过遍历链表,可以在哈希表中找到具有相同键的不同值。这样,即使键相同,不同的值也可以被存储和访问。
  • Redundant Keys(冗余键):这种方法在哈希表中允许存储相同的键,但每个键都关联着不同的值。当发生冲突时,新的键值对可以被插入到相同的哈希桶中,作为已有键的一个冗余副本。通过遍历哈希桶中的冗余键,可以找到具有相同键的不同值。

如下图所示:
在这里插入图片描述
通常为了减少 collision 和 comparisons,Hash Table 的大小应当是 table 中元素量的两倍以上。


  • Robin Hood Hashing: 是 Linear Probe Hashing 的变种,为了防止 Linear Probe Hashing 出现连续区域导致频繁的 probe 操作。基本思路是 “劫富济贫”,即每次比较的时候,同时需要比较每个 key 距离其原本位置的距离(越近越富余,越远越贫穷),如果遇到一个已经被占用的 slot,如果它比自己富余,则可以直接替代它的位置,然后把它顺延到新的位置。
    在这里插入图片描述

  • Cuckoo Hashing (布谷鸟哈希)

本部分参考: 布谷鸟哈希(Cuckoo hash)

首先要理解布谷鸟的行为,这也是算法的核心:

  • 布谷鸟妈妈从不筑巢,它将自己的鸟蛋生在其他鸟类的巢穴里,要别的鸟给它孵蛋
  • 新出生的布谷鸟会本能地将巢穴里的其他蛋踢开(kick out ),推出鸟巢,以确保自己在鸟巢里可以独享宠爱

布谷鸟哈希有几种变种,先介绍一个哈希桶和两个哈希函数的版本:

insert逻辑

  1. 若值x已存在哈希表中,则直接返回
  2. 若insert后哈希表空间会不够,则先进行扩容,再rehash,再继续3、4、5
  3. 用哈希函数h1(x)计算出下标i1,当bucket[i1]为空时,说明鸟巢可用,插入x
  4. 若bucket[i1]非空,用新值x将bucket[i1]上的老值x’踢开(kick out),对应小布谷鸟将老蛋踢出巢穴,老蛋当然也不能坐以待毙,继续kick out别的蛋,老值x’的下一个位置用哈希函数h2(x)寻找
  5. 重复2,直到达到最大循环次数MaxLoop(插入失败);或者所有被踢开的值都找到新位置(插入完成)

lookup逻辑:查找逻辑非常简单,去可能的两个巢穴里寻找,即去下标h1(x)和h2(x)寻找,若没有匹配上,则不存在(从这里可以发现查找是非常快的,且时间复杂度稳定是O(1))

下图展示的是两个哈希函数,两个哈希桶的版本:
在这里插入图片描述
为了防止我们不会陷入一个无限循环中,一旦我们发现了一个死循环或者达到最大循环次数,我们就需要对现有的hash table进行扩容。

  • 如果使用两个hash function,那么我们大概只需要当hash table达到50%容量左右时,才需要进行扩容重建
  • 如果使用三个hash function,那么我们大概需要当hash table达到90%容量的左右时,才需要进行扩容重建

小结

以上介绍的 Hash Tables 要求使用者能够预判所存数据的总量,否则每次数量超过范围时都需要重建 Hash Table。它可能被应用在 Hash Join 的场景下,如下图所示:
在这里插入图片描述
由于 A, B 表的大小都知道,我们就可以预判到 Hash Table 的大小。


Dynamic Hash Tables

与 Static Hash Tables 需要预判最终数据量大小的情况不同,Dynamic Hash Tables 可以按需扩容缩容,本节主要介绍 Chained Hashing,Extendible Hashing 和 Linear Hashing。

Chained Hashing (链式哈希)

Chained Hashing 是 Dynamic Hash Tables 的 HelloWorld 实现,每个 key 对应一个链表,每个节点是一个 bucket,装满了就再往后挂一个 bucket。需要写操作时,需要请求 latch。

在这里插入图片描述

  • 在查找元素时,根据元素的哈希键计算出对应的槽位,并遍历该槽位的链表桶,搜索具有相同哈希键的元素
  • 对于插入和删除操作,也可以看作是查找操作的一般化。在插入元素时,需要进行查找并确定插入位置;在删除元素时,也需要查找并删除相应元素

这么做的好处就是简单,坏处就是最坏的情况下 Hash Table 可能降级成链表,使得操作的时间复杂度降格为 。


Extendible Hashing(可扩展哈希)

在Chained Hashing中,一种可行的方法是在链表变得过长时,将桶(bucket)进行分割,而不是让链表无限增长。这种方法可以避免链表过长导致的性能问题,并且需要进行分割时,只需要对特定的桶进行重新分配。

JDK 1.8中当链表长度达到8时,就将链表转换为红黑树的操作,相信大家都已经背烂了,下面给出一种不同的实现思路。

Extendible Hashing 的基本思路是一边扩容,一边 rehash,如下图所示:

在这里插入图片描述


Linear Hashing(线性哈希)

基本思想:维护一个指针,指向下一个将被拆分的 bucket,每当任意一个 bucket 溢出(标准自定,如利用率到达阈值等)时,将指针指向的 bucket 拆分。

在这里插入图片描述


总结

Hash Tables 提供 O(1) 的访问效率,因此它被大量地应用于 DBMS 的内部实现中。即便如此,它并不适合作为 table index 的数据结构,而 table index 的首选就是下节将介绍的 B+ Tree。

本节参考课程PDF

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

04_前端包管理工具模块化

注意事项: ​ 改模块代码不用重启服务器,修改config文件的时候需要重启服务器 ​ nvm的安装路径和node的安装路径不能在同一路径下面 ​ 有乱码问题使用管理员权限进行使用use方法 下载安装node ​ 使用命令进行安装 1.nvm list 查看已下载所有的node版本 2.nvm install…

leetcode146.手撸 LRU 算法(java)

LRU 缓存 LRU 缓存题目描述LRU 介绍LRU 算法设计代码实现 单调栈算法 LRU 缓存 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/lru-cache 题目描述 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实…

设计模式学习之抽象工厂模式

设计模式系列往期文章 设计模式学习之策略模式设计模式学习之策略模式在前端的应用设计模式学习之简单工厂模式设计模式学习之工厂方法模式 如果你已经理解了工厂方法模式,那你能够很快的明白抽象工厂模式。 温习:什么是工厂方法模式 我们先温习一下…

[muduo学习笔记]事件分发器(Channel、Poller)

此学习笔记参考施磊老师的muduo教学课程。 目的是搞懂 muduo 网络库的核心框架。EventLoop、channel 和 Poller 之间的关系 文章目录 1 Poller 抽象基类2 Channel3 模块的包含muduo模块梳理参考: 整体框架如下: muduo是基于 Reactor 模式的网络库&#…

【前端|HTML系列第2篇】HTML零基础入门之标签元素

大家好,欢迎来到前端入门系列的第二篇博客。在这个系列中,我们将一起学习前端开发的基础知识,从零开始构建网页和Web应用程序。本篇博客将为大家介绍HTML(超文本标记语言)常用标签元素,帮助零基础小白快速入…

基于深度学习的高精度抽烟行为检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要:基于深度学习的高精度抽烟行为检测识别系统可用于日常生活中或野外来检测与定位抽烟行为目标,利用深度学习算法可实现图片、视频、摄像头等方式的抽烟行为目标检测识别,另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5…

虚幻引擎(UE5)-大世界分区WorldPartition教程(一)

文章目录 WC与WP的区别一、如何开启WP1.默认创建WP2.手动创建WP3.转换创建WP 二、设置World Partition参数三、启动流送总结 提示:以下是本篇文章正文内容,下面案例可供参考 WC与WP的区别 WorldCompostion(WC) 是UE4中制作大世界…

Apifox|API 文档和开发闭环初体验

Apifox是一款集文档、接口定义、数据模拟、自动化测试为一体的接口协作平台。 据功能介绍,基本总结Apifox Postman Swagger Mock JMeter 既然评的文章那么多,掀起了一阵子热度,究竟哪些功能: 用下来有哪些体会:…

第7章 Scala集合

第7章 Scala集合 7.1 简介 ​ ​ scala.collection.immutable ​ scala.collection.mutable ​ 7.2 数组 ​ 不可变数组 package chapter07object Test01_ImmutableArray {def main(args: Array[String]): Unit {// 1. 创建数组val arr: Array[Int] new Array[Int](10…

多项目管理难在哪,多项目同时进行该如何做好进度管理?

最近,听到群里的项目经理吐槽,手上有10多个项目同时进行,工作起来手忙脚乱,杂乱无章,让他压力特别大。 对于项目经理来说,多项目并行推进的情况已是常态。从工作层面来说,不仅在各项目之间抢资…

SpringBoo集成MongoDB

一、集成简介 spring-data-mongodb提供了MongoTemplate与MongoRepository两种方式访问mongodb,MongoRepository操作简单,MongoTemplate操作灵活,我们在项目中可以灵活适用这两种方式操作mongodb,MongoRepository的缺点是不够灵活…

购物车业务

一、分析购物车vo (1)添加成功页 public class CartItemVo implements Serializable {/*** 商品id*/private Long skuId;/*** 是否选中*/private Boolean check true;/*** 商品标题*/private String title;/*** 商品图片*/private String image;/***…

如何优雅的将 Docker 镜像从 1.43G 瘦身到 22.4MB

Docker 镜像的大小对于系统的 CI/CD 等都有影响,尤其是云部署场景。我们在生产实践中都会做瘦身的操作,尽最大的可能使用 Size 小的镜像完成功能。下文是一个简单的 ReactJS 程序上线的瘦身体验,希望可以帮助大家找到镜像瘦身的方向和灵感。 …

C++之GNU C的__attribute__((constructor))优先级使用(一百四十九)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…

【期末不挂科 学习数据结构】

期末不挂科 学习数据结构 第一章绪论1.1数据结构的基本概念1.1.1基本概念和术语1.数据2.数据元素3.数据对象4.数据类型5.数据结构 1.1.2数据结构三要素1.数据的逻辑结构2.数据的存储结构3.数据的运算 第一章绪论 1.1数据结构的基本概念 1.1.1基本概念和术语 1.数据 数据是信…

Flutter学习四:Flutter开发基础(四)包管理

目录 0 引言 1 包管理 1.1 简介 1.2 Pub仓库 1.3 依赖Pub仓库 1.3.1 查找包 1.3.2 添加包 1.3.3 下载包 1.3.4 引入包 1.3.5 使用包 1.4 其他依赖方式 1.4.1 依赖本地包 1.4.2 依赖git仓库 1.4.3 不常用的依赖方式 0 引言 本文是对第二版序 | 《Flutter实战第二版…

【ArcGIS】使用ArcMap进行北京1954-120E坐标转WGS84坐标系

背景 在进行青岛地市GIS数据迁移,涉及坐标转换,经过几天摸索终于找到迁移方法 投影坐标系 北京1954-120E坐标 对应为高斯-克吕格投影 300000 3000001 0 0(青岛本地坐标) 增量:-300000 -3000001(此处为示例&#xff0c…

(15)第一人称视角视频

文章目录 前言 15.1 推荐的零件 15.2 连接图示 15.3 通过任务计划器最小化OSD设置 15.4 集成式OSD 15.5 用户视频/博客 15.6 与FPV飞行特别相关的安全警告 15.7 政府/地方法规 前言 第一人称视角在飞行时为你提供了真正的飞行员视角,它将视频摄像机和发射器…

什么是信号槽机制,如何实现,有什么用?(Qt面试题)

1. 什么是信号槽机制? 信号槽机制(Signal-Slot mechanism)是一种在软件开发中常用的设计模式,用于实现对象间的通信和事件处理。该机制最初由Qt框架引入并广泛应用,后来也被其他编程框架和库所采用。 信号槽机制通过定…

Spring Boot 属性配置解析

基于Spring Boot 3.1.0 系列文章 Spring Boot 源码阅读初始化环境搭建Spring Boot 框架整体启动流程详解Spring Boot 系统初始化器详解Spring Boot 监听器详解Spring Boot banner详解 属性配置介绍 Spring Boot 3.1.0 支持的属性配置方式与2.x版本没有什么变动,按照…