【如此简单!数据库入门系列】之无序不代表混乱 -- 堆文件

文章目录

  • 前言
  • 堆文件
  • 链表实现
  • 页目录实现
  • 总结
  • 系列文章


前言

还记得上次遗留的问题吗?

以什么组织方式将数据保存在磁盘中?

今天我们接着讨论这个问题。

首先想一个问题:有一天,你开着自己心爱的大型SUV去超市购物。在停车场入口看到,剩余车紧缺。你该如何先人一步找到合适的车位?

假如,你是这个超市的老顾客,非常熟悉这里停车场的布局和规则,那么你就更有可能快速找到车位。

停车场的布局和规则,类似于数据库中数据文件的文件组织。


堆文件

堆文件是最常见的数据文件组织形式。

堆文件(Heap File):

  • 数据库最常用的文件组织形式,常用于OLTP型数据库
  • 它对页(Page)和记录(Record)没有任何顺序上的要求
  • 可以根据需求,将记录插入任何合适的位置
  • 页和记录的组织方式,完全由实现者自己定义

堆文件通常有两种实现方式:链表和页目录。


链表实现

在这里插入图片描述

在链表实现中:

  • 每个数据页(Data Page)包含记录(Record)、指向下一页和上一页的指针
  • 有一个头页(Header Page)作为文件的开始,用于将数据页划分为满页和空闲页

在链表实现的堆文件中插入一条记录可以分解为三个动作。

1. 找空位置

  • 先找到头页
  • 顺着空闲页链表找一个合适的空位
  • 如果空闲页链表为空,或者找不到合适的位置,则追加一个空闲页到空闲页链表中

2. 将记录写入空位置
3. 必要时更新链表

  • 如果当前空闲页已写满,则将它从空闲页链表移动到满页链表的最前方
  • 把它移到满页链表的最前面,是为了提高效率,因为不用遍历整个满页链表

拿停车举例子(如上图右侧所示)。

假设停车场有A、B、C和D四个区域。每当一个区域停满时,管理员会在区域入口放一个禁止入门的路障。这样司机可以快速找到第一个有空位的区域。

你会沿着箭头的方向找到一个适合的空闲车位:

  • 因为有路障,你快速驶过A区和B区
  • 驶入第一个有空位的区域 - C区
  • 发现C区的唯一的空位太小,大型SUV停不进去
  • 继续驶入下一个有空位的区域 - D区
  • 停入D区最后一个空闲车位
  • 此时,管理员会在D区放置路障

页目录实现

在这里插入图片描述

在页目录的实现中:

  • 每个头页包含一个指向下一个头页的指针,形成页目录
  • 每个头页中的记录包含指向数据页的指针和该页的空闲空间信息
  • 数据页只存储记录,它们不再需要指向相邻数据页的指针

在页目录实现的堆文件中插入一条记录同样分解为三个动作。

1. 找空位置

  • 找到第一个头页,根据头页中记录包含的空闲空间信息,找到一个包含合适空位的数据页
  • 如果当前头页找不到,则继续遍历下一个头页
  • 如果头页链表为空,或者找不到合适位置,则追加新的头页和数据页

2. 将记录写入空位置

  • 顺着头页中记录指向数据页的指针,找到对应的数据页
  • 在数据页中找到对应的空位,写入数据

3. 更新状态

  • 更新头页中有关数据页空闲空间的信息

接着拿停车举例子(如上图右侧所示)。

假设一个停车场经过了信息化改造,在停车场入口处的显示屏上,显示每个区域的每个车位的状态(是否被占用)和信息(车位尺寸)。

你也会沿着箭头的方向找到一个适合的空闲车位:

  • 行驶到显示屏处,找到一个合适的空位,并记录位置(例如D区03车位)
  • 直接行使到D区03车位
  • 显示屏更新D区03车位状态,变为已被占用

总结

我们先从写的角度进行对比:

写入动作链表实现页目录实现
找空位从第一个空闲页开始找
最差情况:追加新的空闲页
平均情况:
- 可能访问较多数据页才能找到合适空位
- 例如1号停车场中存在走冤枉路的问题
顺着页目录开始找
最差情况:追加新的头页和数据页
平均情况:
- 由于空闲信息记录(包含空闲状态和空闲信息)要远小于数据记录
- 因此头页可以包含更多的空闲信息记录
- 也就是说遍历更少的头页就可以找到合适的空位
- 不存在走冤枉路
写记录因为是直接在数据页中找空位,找到空位后直接写入即可,没有额外成本需要从头页中跳转到数据页中的空位,存在额外成本,但成本较低
状态更新记录写入空位后,需要更新数据页头部包含空位状态的信息
最坏情况:额外需要修改数据页的指针,从空闲链表移到满页链表
更新头页中的状态信息

再从删除角度对比:

写入动作链表实现页目录实现
找记录遍历数据页(不考虑所以的情况下)相同
删记录在数据页头部中将对应的记录标记为删除,将数据页插入到空闲页链表头部在数据页头部中将对应的记录标记为删除,更新头页中的空闲信息
辅助成本定期清理空间相同

由此可见:

  • 页目录的优点是插入记录通常更快。只需读取头页就可以找到空位,需要执行的磁盘I/O更少,因此速度更快
  • 页目录适用于频繁地写、更新和删除的场景(数据页中有很多零散的空位)
  • 链表实现更简单,适用于写多,但更新和删除较少的场景(此时空闲页链表尽可能短,磁盘I/O次数尽可能少,找空位时间也尽可能短)

系列文章

更多系列文章,请参考:【如此简单!数据库入门系列】之思想地图 – 系列目录


如果喜欢这篇文章,请不要忘记关注、点赞和收藏哦!
您的鼓励将是我创作的最大动力!

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

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

相关文章

威客网上招标系统(五)

目录 5 详细设计 5.1 系统首页 5.1.1系统首页(网站首页index.jsp) 5.1.2 下沙派威客网首页界面说明 5.2 站内新闻信息 5.2.1站内新闻操作界面 5.2.2系统主操作界面说明 5.3威客在线操作界面 5.3.1 威客在线操作界面 5.3.2威客在线说明 5.4系统…

文件IO-使用dup2实现错误日志功能及判断文件权限,并终端输出

1:使用 dup2 实现错误日志功能 使用 write 和 read 实现文件的拷贝功能,注意,代码中所有函数后面,紧跟perror输出错误信息,要求这些错误信息重定向到错误日志 err.txt 中去 代码: #incl…

kubectl_入门_Pod控制器

Pod控制器 在k8s中,按照pod的创建方式可以将其分为两类 自主式pod:k8s直接创建出来的pod,这种pod删除后就没有了,也不会重建控制器创建的pod:通过控制器创建的pod,这种pod删除了之后还会自动重建 1. 什么…

一张贴纸50万,炒房炒币的怎么都来炒CSGO皮肤了

一张贴纸50万,为什么炒房炒币的都来炒CSGO饰品了? 一张贴纸50万,炒房炒币的怎么都来炒CSGO皮肤了? 经常有人问我,天天看你们买卖装备,买卖皮肤,说到底这都是虚拟产品,看得见摸不着的…

Java_从入门到JavaEE_11

一、抽象类及抽象方法 1.认识抽象类及抽象方法 应用场景:当一个方法必须在父类中出现,但是这个方法又不好实现,就把该方法变成抽象方法,交给非抽象的子类去实现 实例: //抽象类 public abstract class 类名{//抽象方…

element-ui table sortable排序 掉后端接口方式

实例: 官方解释:如果需要后端排序,需将sortable设置为custom,同时在 Table 上监听sort-change事件,在事件回调中可以获取当前排序的字段名和排序顺序,从而向接口请求排序后的表格数据。 1.table上要加 sort-change"sortCha…

鸿蒙OpenHarmony开发板:【子系统配置规则】

子系统 子系统配置规则 通过build仓下的subsystem_config.json可以查看所有子系统的配置规则。 {"arkui": {"path": "foundation/arkui", # 路径"name": "arkui" # 子系统名},"ai": {&q…

【Keil程序大小】Keil编译结果Code-RO-RW-ZI分析

【Keil程序大小】Keil编译结果Code-RO-RW-ZI分析 下图为keil编译后的结果: 单位为Byte。Code是程序大小。RO是常量大小。RW是读写变量占用大小,如已初始化的静态变量和全局变量。ZI是全零变量占用大小,如未初始化的static修饰的静态变量、全局…

项目管理-项目绩效域2/2

项目管理:每天进步一点点~ 活到老,学到老 ヾ(◍∇◍)ノ゙ 何时学习都不晚,加油 八大绩效域包括:“团干部 策划开公交” 团队、干系人、不确定性、测试、规划、开发方法与生命周期、项目工作、交付。 上节…

在全志H616核桃派1B开发板Python进行GPIO按键功能实现

前言​ 按键是最简单也最常见的输入设备,很多产品都离不开按键,包括早期的iPhone,今天我们就来学习一下如何使用Python来编写按键程序。有了按键输入功能,我们就可以做很多好玩的东西了。 实验目的​ 编程实现按键输入检测。 …

Python从0到POC编写--SQL注入

SQL注入POC编写。 环境: win10 ,phpStudy ,python3.7 ,sqli-labs 虚拟域名: www.sql.com 简单的POC: 说起来也简单, 就是请求–>响应, 然后再判断返回信息是否存在注入。 本…

linux虚拟机配置环境

1.配置虚拟机 在VMware中安装CentOS7(超详细的图文教程)_在vmware上安装centos-CSDN博客https://blog.csdn.net/qq_45743985/article/details/121152504 2.固定虚拟机ip地址 Vmware虚拟机Linux配置固定IP地址(详细版)_虚拟机固…

华为数据之道第四部分导读

目录 导读 第四部分 第10章 未来已来:数据成为企业核心竞争力 数据:新的生产要素 数据被列为生产要素:制度层面的肯定 数据将进入企业的资产负债表 数据资产的价值由市场决定 大规模数据交互的企业数据生态 数据生态离不开底层技术的…

OpenHarmony 4.0 实战开发——分布式软总线解析:设备发现与传输

OpenHarmony 的分布式软总线子系统为 OpenHarmony 系统提供的通信相关的能力,包括:WLAN 服务能力、蓝牙服务能力、软总线、进程间通信 RPC(Remote Procedure Call)等通信能力。 其中主要包括: WLAN 服务:…

使用unplugin-icons报错:Icon `eos-icons/ai` not found

代码: import IconNanobert from ~icons/eos-icons/ai 报错: Icon eos-icons/ai not found解决办法: npm i -D iconify-json/eos-icons (把eos-icons替换成报错的那个collection-id即可,collection-id名称见图2&…

CTF-reverse,逆向分析,对“左移4或右移4,即(x<<4) | (x >>4)的加密探讨

博主在刷题过程中遇上这样一个有意思的加密(如下图),苦苦思索其逆向运算,被硬控了很久,也没搜到什么资料来解释这个问题(也许是太简单??蒟蒻博主怀疑人生……) 经过博主不…

[C++]哈希应用-布隆过滤器快速入门

布隆过滤器 布隆过滤器(Bloom Filter)是一个由布隆在1970年提出的概率型数据结构,它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器的主要特点是高效的插入和查询,可以用于检索一个元素是否在一个集合中。 原理…

Springboot整合飞书向群组/指定个人发送消息/飞书登录

Springboot整合飞书向群组发送消息 飞书开放平台创建企业自建应用 添加应用能力-机器人 创建完成后,进入应用详情页,可以在首页看到 App Id 和 App Secret 在飞书pc端创建一群机器人 此处可以拿到该机器人的webhook地址,通过https的方式,也可以调用发送…

JavaEE企业级开发中常用的JDK7和JDK8的时间类

JDK7时间类 全世界的时间有一个统一的计算标准 在同一条经线上的时间是一样的 格林威治时间 简称GMT 计算核心 地球自转一天是24小时 太阳直射正好是12小时 但是误差太大 现在用原子钟来代替 用铯原子震动的频率来计算时间,作为世界的标准时间UTC 中国标准时间…

Spring-依赖注入的处理过程

前置知识 1 入口 DefaultListableBeanFactory#resolveDependency 2 每个依赖都有对应的DependencyDescriptor 3 自定绑定候选对象处理器AutowireCapableBeanFactory 注入处理 我们可以看到AutowireCapableBeanFactory中有两个方法: 第一个是单个注入:…