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

news2024/12/26 2:46:29

文章目录

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


前言

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

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

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

首先想一个问题:有一天,你开着自己心爱的大型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.coloradmin.cn/o/1653501.html

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

相关文章

Python中tkinter编程入门1

1 tkinter库简介 tkinter是Python的标准库,用来进行GUI(Graphical User Interface,图形用户界面)编程。 2 导入tkinter库 tkinter是Python默认的GUI库,因此,IDLE中已经包含了该库,使用时无需…

爱奇艺文娱知识图谱的构建与应用实践

2012年5月,Google发布了知识图谱(Knowledge Graph),以提升搜索引擎返回的答案质量和用户查询的效率。有了知识图谱作为辅助,搜索引擎能够洞察用户查询背后的语义信息,返回更为精准、结构化的信息,更大可能地满足用户的…

抖音小店怎么运营?最全的运营攻略来了?

大家好,我是电商糖果 很多开好店铺的小伙伴,都会遇到一个难题,那就是不会运营店铺。 可能好几个月才出十几单,甚至体验分都没有弄出来。 说实话,这种情况糖果见多了。 糖果做抖音小店也有四年多了,也开…

STM32F1#1(入门了解)

一、STM32开发平台和工具 1.1 STM32芯片介绍 典型微控制器由CPU(运算器、控制器)、RAM、ROM和输入输出组成。 1.2 STM32核心板 STM32核心板配件: ①JTAG/SWD仿真-下载器 ②通信-下载模块 ③OLED显示屏 1) 通信-下载模…

uniapp 小程序图片懒加载组件 ImageLazyLoad

预览图 组件【ImageLazyLoad】代码 <template><viewclass"image-lazy-load":style"{opacity: opacity,borderRadius: borderRadius rpx,background: background,transition: opacity ${time / 1000}s ease-in-out,}":class"image-lazy-loa…

请大数据把我推荐给正在申请小程序地理位置接口的人

小程序地理位置接口有什么功能&#xff1f; 若提审后被驳回&#xff0c;理由是“当前提审小程序代码包中地理位置相关接口( chooseAddress、getLocation )暂未开通&#xff0c;建议完成接口开通后或移除接口相关内容后再进行后续版本提审”&#xff0c;那么遇到这种情况&#x…

Python程序设计 函数(三)

练习十一 函数 第1关&#xff1a; 一元二次方程的根 定义一个函数qg&#xff0c;输入一元二次方程的系数a,b,c 当判别式大于0&#xff0c;返回1和两个根 当判别式等于0&#xff0c;返回0和两个根 当判别式小于0&#xff0c;访问-1和两个根 在主程序中&#xff0c;根据函数返回…

c 双向链表

图片 #include <stdio.h> #include <stdlib.h> #include <string.h>int main(void){ struct film{char name[20];int id;struct film *pre; //前向指针struct film *next; //后向指针 };struct film *headNULL;struct film *ls,*lspre,*work;in…

微信小程序16: 组件通信

父子组件之间的通信 父子组件通信一共有三种方式 属性绑定 用于父组件向子组件的指定属性设置数据&#xff0c;仅能设置JSON兼容的数据 事件绑定 用于子组件向父组件传递数据&#xff0c;可以传递任意数据 获取组件实例 父组件还可以通过this.selectComponent()获取子组件的实…

【C++】:模板初阶

目录 一&#xff0c;泛型编程二&#xff0c;函数模板2.1 函数模板概念2.2 函数模板格式2.3 函数模板的原理2.4 函数模板的实例化2.5 模板参数的匹配原则 三&#xff0c;类模板3.1 类模板的定义格式3.2 类模板的实例化 一&#xff0c;泛型编程 在C语言中如何实现一个通用的交换…

在Leaflet中点对象使用SVG和Canvas两种模式的对比

目录 前言 一、关于SVG和Canvas 1、SVG知识 2、Canvas知识 3、优缺点 二、SVG和Canvas在Leaflet的使用 1、相关类图 2、Leaflet的默认展示方式 三、SVG和Canvas实例及性能对比 1、SVG模式及性能对比 2、Canvas优化 总结 前言 众所周知&#xff0c;在Leaflet当中&#…

我独自升级下载 我独自升级崛起一键下载安装

近期&#xff0c;动画《我独自升级》凭借其高涨的人气&#xff0c;迅速席卷了各大平台&#xff0c;其热度非凡。乘着这股风潮&#xff0c;韩国知名厂商网石集团火速推出了同名游戏力作《我独自升级&#xff1a;ARISE》&#xff0c;让众多粉丝得以跨越次元壁垒&#xff0c;亲自投…

批量图片重命名及汇总

又一堆图片文件需要处理... 源文件分布&#xff1a; 有N个文件夹&#xff0c;每个文件夹下又有M个子文件夹&#xff0c;每个子文件夹下有X张图片。 例如文件夹A下有子文件夹A1,A2,A3&#xff0c;子文件夹A1下有图片a-1,a-2,a-3...... 处理目标&#xff1a; 1、将所有图片汇…

qt开发解压缩zip文件实现

作者开发环境&#xff1a;Qt5.8 &#xff0c;win10 总体思路&#xff1a;首先我们编译zip源码&#xff0c;生成zip的动态库&#xff1b;然后再编译quazip源码&#xff0c;得到quazip的动态库&#xff1b;最后在我们的程序中去调用。 详细步骤&#xff1a; 1、编译zlib zlib…

HackMyVM-Slowman

目录 信息收集 arp nmap whatweb WEB web信息收集 gobuster FTP匿名登录 hydra mysql爆破 mysql登录 fcrackzip爆破 hashcat爆破 ssh登录 提权 系统信息收集 python Capabilities提权 信息收集 arp ┌──(root㉿0x00)-[~/HackMyVM] └─# arp-scan -l Interf…

有哪些渠道找到海外代理IP服务?

在今天的全球化时代&#xff0c;许多企业和个人都需要跨越国界&#xff0c;与世界各地的资源、信息和市场进行连接。海外代理IP服务成跨境在线业务增效的重要的工具&#xff0c;可以帮助拓展业务宽度&#xff0c;以实现更多样化的业务需求。但是&#xff0c;如何找到合适、安全…

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

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

STM32使用ADC单/多通道检测数据

文章目录 1. STM32单片机ADC功能详解 2. AD单通道 2.1 初始化 2.2 ADC.c 2.3 ADC.h 2.4 main.c 3. AD多通道 3.1 ADC.c 3.2 ADC.h 3.3 main.c 3.4 完整工程文件 1. STM32单片机ADC功能详解 STM32单片机ADC功能详解 2. AD单通道 这个代码实现通过ADC功能采集三脚电…

回答篇:测试开发高频面试题目

引用之前文章&#xff1a;《测试开发高频面试题目》 https://blog.csdn.net/qq_41214208/article/details/138193469?spm1001.2014.3001.5502 本篇文章是回答篇&#xff08;持续更新中&#xff09; 1. 什么是测试开发以及其在软件开发流程中的作用。 a. 测试开发是指测试人员或…

MySQL LRU算法(冷热数据分离)

背景 MySQL中使用的InnoDB存储引擎采用了一种特别的最近最少使用&#xff08;LRU, Least Recently Used&#xff09;算法来管理其Buffer Pool中的页&#xff08;包括数据页和索引页&#xff09;。Buffer Pool是InnoDB用来缓存数据&#xff0c;以减少磁盘I/O操作的内存区域。正…