【数据库】基于散列的两趟算法原理,以及集合与包的并,差,交,连接操作实现原理,执行代价以及优化

基于散列的两趟算法

专栏内容

  • 手写数据库toadb
    本专栏主要介绍如何从零开发,开发的步骤,以及开发过程中的涉及的原理,遇到的问题等,让大家能跟上并且可以一起开发,让每个需要的人成为参与者。
    本专栏会定期更新,对应的代码也会定期更新,每个阶段的代码会打上tag,方便阶段学习。

开源贡献

  • toadb开源库

个人主页:我的主页
管理社区:开源数据库
座右铭:天行健,君子以自强不息;地势坤,君子以厚德载物.

文章目录

  • 基于散列的两趟算法
  • 前言
  • 概述
  • 原理
  • 流程
  • 基于散列的去重
  • 基于散列的分组聚集
  • 基于散列的并、交和差
  • 基于散列的连接
  • 代价分析
  • 总结
  • 结尾

在这里插入图片描述

前言

随着信息技术的飞速发展,数据已经渗透到各个领域,成为现代社会最重要的资产之一。在这个大数据时代,数据库理论在数据管理、存储和处理中发挥着至关重要的作用。然而,很多读者可能对数据库理论感到困惑,不知道如何选择合适的数据库,如何设计有效的数据库结构,以及如何处理和管理大量的数据。因此,本专栏旨在为读者提供一套全面、深入的数据库理论指南,帮助他们更好地理解和应用数据库技术。

数据库理论是研究如何有效地管理、存储和检索数据的学科。在现代信息化社会中,数据量呈指数级增长,如何高效地处理和管理这些数据成为一个重要的问题。同时,随着云计算、物联网、大数据等新兴技术的不断发展,数据库理论的重要性日益凸显。

概述

前面两篇博客分享了基于排序的两趟算法,那么还有其它类型的两趟算法吗?

答案是肯定的,当然有。

本文就来分享一种基于散列的两趟算法。

原理

如果数据量太大以至于不能一次装入内存缓冲区中,基于散列的两趟算法中,采用一个合适的hash算法,将表划分为M-1个hash桶,这样操作对象一样的元组就在相同的桶中,然后就可以依次处理各桶中的数据。

实际上,经过hash处理之后,我们将操作对象的大小减小了,减小的比例等于桶的数目,它的数量大致为可用缓冲区大小M。这与我们介绍的基于排序的两趟算法有点类似,有同样的因子,但是两种方法执行的过程完全不同。

流程

第一趟hash散列处理:

  • 假设hash函数为h,并且h将表R的整个元组作为参数,同时将每个一个hash桶与一个缓冲区块联系起来。
  • 每次加载表R的一个数据块,将块中的元组按hash函数h进行处理,输出到桶对应的缓冲区中;
  • 如查某个桶对应的缓冲区满了,将它写到磁盘上;
  • 重复以上步骤,直到表R处理完成;
  • 最后一个桶的缓冲区也写到磁盘上;

第二趟处理,就需要结合具体的某个操作,我们之前介绍过去重,分组聚集,并集,差集,交集,连接等;

基于散列的去重

在第一趟hash散列结束后,对于hash相同的元组都在一个桶中,那么相同的元组也在一个桶中,我们每次处理一个桶。

  • 读取第一个桶的数据块到缓冲区中;
  • 将第一条元组输出到结果缓冲区中,对于它的副本忽略;
  • 依次处理下一个桶中的数据块;
    直到所有桶中的数据块处理完成;

基于散列的分组聚集

执行分组操作的话,在第一趟将表R的数据hash成M个桶的进候,hash的键值要使用分组属性列,这样相同分组属性的元组会被分配到相同的桶中。

在第二趟时,依次加载每个桶的数据块,计算分组数据,如行数,求和等,每个桶为一个分组,直到所有桶处理完毕。

最后计算分组结果,输出结果。

基于散列的并、交和差

第一趟,将表R和表S分别采用相同的hash函数h,分别hash到数量相等的桶中,那么桶的数量为2M;

第二趟时,对于不同操作:

  • 对于集合的并,因为相同的元组分配在相同的桶中,比如表R的每i个桶记为Ri,而表S的第i个桶记为Si;那么取Ri和Si执行并集操作,对于两个中都出现的元组,重复元组只输出一次到结果缓冲区块上;这样依次对应取两个桶,直到所有桶处理完毕。

  • 对于包的并,也是对应的取Ri和Si两个桶的数据块,将两个桶中的数据,输出到结果缓冲区中;其实一趟算法就足够了;

  • 对于集合交,也是对应的取Ri和Si两个桶的数据块,对于两个桶中都出现的元组输出到结果缓冲区中;

  • 对于包的交,加载对应的取Ri和Si两个桶的数据块,对于出现次数相同的元组,输出到结果缓冲区中;

基于散列的连接

假设表R(X,Y)与表S(Y,Z)进行等值连接;

第一趟,将表R和表S分别采用相同的hash函数h,分别hash到数量相等的桶中,那么桶的数量为2M,而hash键值采用两表的连接属性列,这样对于属性列Y相同的元组都在Ri与Si桶中。

第二趟时,对于对应的Ri与Si桶加载到内存中,采用一趟散连连接算法就可以完成。

代价分析

将表R,在第一趟hash成M个桶时,会读取表R的所有数据块B,然后将各个桶对应的数据块写到磁盘上,写磁盘的数据块也近似为B;

在第二趟中,会将各桶的数据块读出,数据块数为B;如果不计结果的写入。

那么在整个基于散列的两趟算法中,磁盘IO的数量为表R的数据块的数量的3倍。

总结

对于大表来讲,不能一次性加载到内存,那么我们可以采用基于散列的两趟操作,实现一元操作去重,分组和聚集,二元操作并,差,交,连接等。

以下是使用访问者模式编写输出"Hello World"的C语言代码:

#include <stdio.h>// 定义抽象数据类型
typedef struct {void (*accept)(void *data, void (*print)(void *data));
} Visitor;// 定义具体数据类型
typedef struct {char message[100];
} Data;// 定义访问者函数
void printVisitor(void *data) {Data *myData = (Data *)data;printf("%s\n", myData->message);
}// 定义具体数据类型的构造函数和访问者函数调用
Visitor visitor = { .accept = printVisitor };
Data data = { .message = "Hello World" };
data.accept(&visitor, printVisitor);

在上述代码中,我们定义了一个抽象数据类型Visitor,其中包含一个accept方法,用于接受具体数据类型的实例并调用其访问者方法。接着,我们定义了一个具体数据类型Data,其中包含一个字符串消息。然后,我们定义了一个访问者函数printVisitor,用于输出具体数据类型的字符串消息。最后,我们定义了一个具体数据类型的构造函数和访问者函数调用,创建了一个Data实例并使用accept方法将其传递给访问者对象,并调用访问者函数输出字符串消息。

结尾

非常感谢大家的支持,在浏览的同时别忘了留下您宝贵的评论,如果觉得值得鼓励,请点赞,收藏,我会更加努力!

作者邮箱:study@senllang.onaliyun.com
如有错误或者疏漏欢迎指出,互相学习。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

shiro整合redis

shiro整合redis 前言&#xff1a;shiro默认的session是存储在jvm内存中的&#xff0c;这样会导致java服务内存占用更大以及一旦服务器宕机或者版本迭代需要重启服务时&#xff0c;缓存中的数据不能恢复&#xff0c;导致用户需要重新登录认证&#xff0c;体验很差。因此利用第三…

JavaScript 表达式

JavaScript 表达式 目录 JavaScript 表达式 一、赋值表达式 二、算术表达式 三、布尔表达式 四、字符串表达式 表达式是一个语句的集合&#xff0c;计算结果是个单一值。 在JavaScript中&#xff0c;常见的表达式有4种&#xff1a; &#xff08;1&#xff09;赋值表达式…

CopyOnWriteArrayList源码解析

CopyOnWriteArrayList源码解析 文章目录 CopyOnWriteArrayList源码解析一、CopyOnWriteArrayList二、总结 一、CopyOnWriteArrayList 在 JUC 中&#xff0c;对于 ArrayList 的线程安全用法&#xff0c;比较推崇于使用 CopyOnWriteArrayList &#xff0c;那么CopyOnWriteArrayL…

前端 | iframe框架标签应用

文章目录 &#x1f4da;嵌入方式&#x1f4da;图表加载显示&#x1f4da;100%嵌入及滑动条问题&#x1f4da;加载动画保留 前情提要&#xff1a; 计划用iframe把画好的home1.html&#xff08;echarts各种图表组成的html数据大屏&#xff09;嵌入整合到index.html&#xff08;搭…

API接口测试工具的主要作用及选择指南

API接口测试是现代软件开发中至关重要的一环。为了确保不同组件之间的无缝集成和功能正常运作&#xff0c;API接口测试工具应运而生。本文将介绍API接口测试工具的主要作用&#xff0c;以及在选择适合项目的工具时需要考虑的因素。 1、功能测试&#xff1a;API接口测试工具的首…

多线程访问资源计数不正确问题分析

线程1&#xff1a;首先修改状态为-1&#xff0c;然后分配资源&#xff0c;资源分配成功后&#xff0c;修改状态为0 线程2&#xff1a;查询状态为-1&#xff0c;然后分配资源&#xff0c;资源分配成功后&#xff0c;修改状态为0 存在这种情况&#xff0c;在线程1修改状态为-1时&…

云服务器哪家便宜?亚马逊AWS等免费云服务器推荐

在这数字化的时代&#xff0c;云计算技术越来越广泛应用于各种场景&#xff0c;尤其是云服务器&#xff0c;作为一种全新的服务器架构正在逐渐取代传统的物理服务器&#xff0c;“云服务器哪家便宜”等用户相关问题也受到越来越多的关注。自从亚马逊最早推出了首个云计算服务—…

RF Power Generator射频源维修射频匹配器维修

RF MATCH射频匹配器维修范围有ADVANCED射频电源匹配器&#xff1b;ASTEX射频电源匹配器&#xff1b;NP射频电源匹配器&#xff1b;ASTECH射频电源匹配器&#xff1b;SEREN射频电源匹配器&#xff1b;射频电源匹配器&#xff1b;KYOSAN射频电源匹配器&#xff1b;ENI射频电源匹配…

5.3 Windows驱动开发:内核取应用层模块基址

在上一篇文章《内核取ntoskrnl模块基地址》中我们通过调用内核API函数获取到了内核进程ntoskrnl.exe的基址&#xff0c;当在某些场景中&#xff0c;我们不仅需要得到内核的基地址&#xff0c;也需要得到特定进程内某个模块的基地址&#xff0c;显然上篇文章中的方法是做不到的&…

【Java Spring】SpringBoot常用插件

文章目录 1、Lombok1.1 IDEA社区版安装Lombok1.2 IDEA专业版安装Lombok1.3 Lombok的基本使用 2、EditStarters2.1 IDEA安装EditStarters2.2 EditStarters基本使用方法 1、Lombok 是简化Java开发的一个必要工具&#xff0c;lombok的原理是编译过程中将lombok的注解给去掉并翻译…

基于SpringBoot的公益慈善平台

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取项目下载方式&#x1f345; 一、项目背景介绍&#xff1a; 基于SpringBoot的公益…

sqli-labs靶场详解(less29-less31)

less-29 提示有最好的防火墙 小白原因 这种题型没见过 先自己测试一下 ?id1 to use near 1 预计可以使用报错注入 和单引号有关的注入点 ?id1 and 11 成功 ?id1 and 12 失败 确实是单引号字符型注入点 ?id1;%00 id1%27;%00 获取到了%00空字符&#xff08;原因就是服务器获取…