CMU15-445 数据库导论 Storage01
CMU15-445 01 Storage
1. 参考资料:
[1] CMU15-445:Database Systems [Andy Pavlo] https://15445.courses.cs.cmu.edu/fall2022
[2] DataBase System Concept[M].Abraham Silberschatz,Henry F. Korth,S. Sudarshan
[3] Simviso精选视频课程.知秋译:https://www.simtoco.com/#/albums?id=1000013
[4] 课件链接: 链接: https://pan.baidu.com/s/1s2oBK93GbphPwS4GO_ml5Q 提取码: eah4
2. 概述:
本篇是数据库设计的第一个篇章,整个课程的第三篇,主要着眼于一下几点:
-
介绍数据库设计的主流结构,并对数据库类软件的层次进行了剖析;
-
着重介绍数据库类文件在磁盘上是如何进行存储的,包括
File storage:数据库文件在磁盘上的存储;
Page Layout: 数据库存储时页的概念,并介绍页的布局设计;
Tuple Layout: 数据存储中record(行)的布局设计;并且介绍了数据库系统是如何对Paeg内部的tuple进行管理的;
-
通过数据库来实现数据从disk <--->memory之间的流动管理,本部分主要在下一节课Storage2中讨论;
3. 存储的基本介绍:
3.1 基础概念
众所周知,当前主流计算机架构中,程序在未运行时将数据存储在磁盘(disk)中,而在
进程启动后就会将数据从磁盘加载至内存(memory),对其进行高效率的访问和使用。
当数据位于不同位置时具有如下特点:
-
Disk:
磁盘通过磁性介质对数据进行存储,稳定性较强,不易失(Non-volatile),因此对于将数据写入磁盘的行为也被称为持久化;
其存储容量大,且价格较低;
但是对磁盘读写进行读写时速度较慢,并且操作系统对磁盘进行访问时,是by扇区进行地址访问的,无法by字节进行访问,如果你想对这个扇区下的某个地址进行访问,需要将本扇区加载进memory, 再进行访问;
-
Memory:
内存中的数据,可以对其进行by Bit的访问,可以直接通过在内存中的地址,对指定位置的数据进行读写;
内存访问速度远快于磁盘,但价格较贵,且容量较小;
DataBaseSystem(后序系列文章中简述为DBS)必须要大批量的管理数据,存储在磁盘上的数据量远大于内存容量,因此DBS和Disk的交互,有以下两个痛点:
-
- 数据库需要通过合理的设计,迅速找到目标数据所在的区域,将对应的数据加载到memry进行解析;(时间)
-
- 数据库需要对存储空间,内存分布进行管理,尽量减少对磁盘和内存的消耗(空间);
3.2 面向磁盘的数据库设计(Disk-Oriented DBMS)
面向磁盘的数据库设计,指的是将数据文件以特定的编码格式,存储在磁盘上。文件内部以Page的形式来对数据进行管理。文件中存在一个目录(Directory),对Page进行索引。
当查询引擎(query-engine)发送来一条查询引擎时,执行引擎(query-engine)会唤起缓存池(buffer-pool),让其将特定的Page加载进内存中,然后对本页进行解析,查询需要的数据。
4. FileStorage
大多数的DBS会把数据存在Disk上(Redis,存在memory上)。操作系统并不关心文件的内容。DBS用自己的编码方式给数据进行编码,然后进行存储。(DBS同样会数据进行压缩处理);
5. DataBase Page
DBS将文件中一个or多个分割好的文件,称为一个Page。一个Page中可以包含不同类型的数据信息(data, index, 表信息等)。但是大多数系统中都不会这么做,是每类数据分开存储。但是部分数据库(Oracle),会要求每个Page可以自解释,即把解析表需要的基础进行包含在Page内。
每个Page,存在一个独有ID,实际这个ID表示了该Page在文件中的偏移量,可以通过这个偏移量在文件中找到对应Page的位置。
5.1 Page的大小
1.可变:
如果系统中Page大小是可变的,那么系统需要增加一个功能,即调整File中的Page排布,通过这样来防止文件中的碎片空间存在;
2.定长:
如果Page定长,只需要在文件中空位置插入新Page即可,无需内存调整,但是如果多次进行Page的增删操作,Page较为稀疏时,可能会造成空间的浪费;
5.2 Page的原子性操作
由于物理特性的限制,操作系统每次读写操作为一个扇区(4KB),如果DBS和DISK交互大于这个大小的话,我们就需要在每次读写时进行一些额外的操作(例如数据截断,分批插入等),这就不能保证每次操作的原子性(atomic),当一次写入crashes时,我们的操作可能会从中间截断,引发各种Bug;
5.3 PageLayout
Page结构由两部分组成;Header,Data
PageHeader,常用以存储当前Page的基本信息:
- PageSize: 页面大小;
- Checksum: 校验码,可以通过校验码来验证Page数据是否完备;
- DBMS version: 版本号,用来做向前兼容;
- Transaction Visibility: 事务控制(待补充);
- Self-containment 自实现字段,上文提到的Oracle;
Data: 数据段,常见的有稻草人(strawman)模式和槽模式(slot)两种,稻草人模式实际就是顺序紧密排布,不多缀述。实际设计中,最多的是slot模式
page的数据段,先在其实位置存储一个sloat array, 其中存储量每个Tuple相对于当前Page的偏移量。一个tuole 插入时,先去存入sloat array中,再插入数据。
这样的存储方式下,我们可以通过Pageid+sloat[i],就可以确认tuple在文件中的位置,即使page发生了改变,只要PageID指向正确地址,我们也能找到对应的tuple;
当我们维护tuole(insert or delete)时,我们可以根slot_array去索引位置(可以在其中保存tuple的长度等相关信息),快速对Page进行整理;
6. Tuple Layout
Tuple Header:
- 控制标志,当前tuple是否被lock等;
- Null标记;
值得一提等是,设计时尽量不要把表信息写进tuple,会导致设计复杂;
Tuple Date:
没什么特殊的,实际存储的二进制数据
Unique Identifier:
每个tuple在本数据库中有个唯一识别码;
通常是page_id + offert;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?