烹饪肉类视频地址:
本课程主要是关于如何开发全面的数据库管理系统,而不是如何编写复杂的SQL查询和设计最合理的关系模型数据库表。本课程将告诉您设计数据库管理系统所需的这些技术堆栈顶部:
涉及的主题包括:
面向磁盘的数据库系统就是这样的系统。该软件假设数据库的主要搜索位置位于磁盘上。这意味着执行可能访问不在内存中的数据的查询。它需要将数据从非易失性(例如磁盘)加载到挥发性存储(例如内存)。
计算机存储级别的结构如上图所示。尺寸越大,尺寸越小,成本越昂贵,但是访问速度越快,大小越大,成本越低,访问速度就越慢。这些包括:
在本课程中,您将不在乎CPU寄存器和缓存。DRAM将被视为内存(内存),而SSD,HDD和网络存储被视为磁盘(磁盘)。我们只关心内存和磁盘。
实际上,这里有一些新的存储空间,可能会破坏这些边界,例如:
让我们看一下访问这些不同存储的大约时间(互联网上有很多数字,我们只需要注意幅度)
因此,我们的数据库管理系统的目标,尽管我们要存储一个可以超过可用内存容量的数据库,但我们希望对应用程序提供幻想,即,我们有足够的内存将整个数据库存储在内存和使用某些cachecalcalcalcalcal对某些数据提前进行,允许不同的线程或不同的查询同时运行,以避免由于每次或写作而撰写或读取磁盘而导致低执行效率。
我们要在本课程中设计的是基于磁盘持久性的DBM,如上图所示:
对于前面提到的内存和缓冲池,那些学习操作系统或熟悉操作系统的人可能知道操作系统具有相似的机制,为什么不使用系统调用来使用操作系统的现有机制来实现什么关于缓冲池?例如,mmap()(系统调用内存映射文件),让我们看一下下面所示的场景:
如果我们使用MMAP(),我们只需将此缓存到期和完整的内存管理即可执行操作系统。操作系统不知道我们的业务方案,并且哪些缓存已过期。从应用程序的角度来看,我可能需要阅读不在内存中的内容,并且缺乏页面中断。我们可以将其移交给另一个线程以执行此操作,而无需阻止当前线程,以便当前线程可以对其他请求进行评估可以增加吞吐量。它足以仅优化阅读场景,但是如果涉及写作,则此优化不是足够的:
由于操作系统被告知要编写数据,因此操作系统将不合适(例如批处理编写,将内存块汇总在一起并减少内存中断)。
我们还可以使用一些系统来优化:
还有一些系统呼吁我们告诉操作系统如何操作MMAP内存:
主流数据库(例如MySQL,Postgres,Oracle,SQLServer等)没有使用MMAP,并且大多数使用的人也在考虑更换MMAP。
因此,我们总结:
如果您将内存管理的全部功能移交给操作系统,操作系统可能会做出一些对您的性能有害的决策,DBMS通常希望自己控制内存管理策略,以便它可以带来:
该数据库实际上是磁盘上的一个或多个文件。例如,SQLITE的整个数据库都在一个文件中,并且大多数其他数据库(例如MySQL)都分为不同的文件。SQLITE本身是一个轻量级的系统。通常考虑存储性能和限制的MySQL将分为不同的文件。在当前文件系统中,文件大小限制不是考虑。pb文件,而是像FAT32之类的旧文件系统一样,仅支持2GB大小。我们在此处提到了文件系统。文件系统实际上是操作系统提供的操作文件的API。我们使用这些API操作文件(该文件实际上是一堆存储块)。大多数数据库取决于操作系统提供的文件系统。一些制造商为自己的数据库产品提供了自己的本机文件系统,但这失去了迁移的灵活性并部署在云上。
我们要在这里实现的是DBMS的存储管理器存储管理器。上述数据库文件将被管理。我们将在此处向操作系统发送阅读和写作请求。操作系统将安排这些读取和写入。相对较高的系统还将优化这些系统调度,即此文件系统上的中介层摘要。在此中间类管理中,操作系统管理的调度。请求彼此接近,此中产阶级将组合在一起形成写作请求。我们在这里不要这样做,这太复杂了。
在这些文件中,它们由页面组织,由一组页面组成。我们将记录这些页面的读取和编写页面尺寸(例如,可以存储在新数据中的哪些页面和空格,哪些页面,哪些页面有肮脏的数据,这些数据尚未被刷到磁盘中,其中页面完全满)
该页面实际上是一个固定的 - 大小数据块,所有相关数据在页面中的数据库中,例如数据,元数据,索引和日志记录。需要包含页面,也就是说,关于如何解释和理解页面的内容,我们需要的所有信息必须存储在页面本身中。这样,即使您丢失了任何页面,也不会影响该页面分析和使用任何其他页面。如果您将元数据存储存储在不同页面上的元数据数据分开,如果元数据页面丢失或损坏,则无法解析元组数据页面,则该自由度设计更好。灾难恢复。
尽管在页面上存储了不同类型的数据(例如元数据数据,元数据,索引和日志记录),但通常不存储不同类型的数据。一些基于研究的数据库可能会在同一页面上存储不同类型的数据同一页面,但大多数系统尚未这样做。
每个页面都有唯一的标识符,该标识符是页面ID(页面ID)。我们使用此唯一标识符形成中间层。在此中间层中,以维护页面ID的位置和实际存储文件的位置,我们可以找到相应的文件位置并通过页面ID读取此页面。,我们要扩展存储,压缩存储和使用等),页面ID不会更改,但是我们修改了文件位置,使用文件位置存储直接存储更方便DBMS的其他层不需要关心这一点,只会记录页面ID。在修改页面位置时,我们不需要告诉其他层要修改同一层。
我们有许多不同的层面可以具有页面的概念:
数据库页面很大,因此您可以在单个页面上保存更多数据,因此将减少提到的页面目录的大小。页面目录用于查找所有页面的位置。通常,它将始终存在于内存中的页面目录越小,CPU缓存命中率越高。同一页面上的更多数据,读取数据也逐页读取,这也适用于cache pre -collection.however.however。,相应地,写作也是一个页面和一页,并且写作消费所带来的更大。这就是为什么这些商业数据库允许您调整页面大小的原因。
因此,如何设计文件页结构,通常有三种类型:
数据库堆文件是一个无序的页面集合,可以随机存储数据组数据。穿过所有页面的API。
同时,我们需要一些页面的元数据进行跟踪,以便我们可以快速找到需要插入新数据时插入的位置。
通常,我们通过页面目录(页面)设计桩文件中的结构,但首先,我们首先通过链接列表设计文件结构,以了解为什么此方法很愚蠢。
如果您使用链接列表设计,通常我们将维护一个标题页面。在此页面上,我们保持了两个指针。一个指针是指向所有剩余空间的所有页面的指针。页面列表指针。链接的列表均为两个 - 路链接列表。我们可能会按顺序进行遍历或遍历:订单遍历通常用于查找适当的位置,例如找到足以容纳数据空间的页面,通常用于移动。这不是一种更好的设计方法,主要是因为效率是因为效率插入和更新相对较低
这是一种更设计的方法,即页面目录。我们维护专门用于存储目录的页面。在此目录中,可以将特定文件位置偏移到特定文件位置位置的映射可以简要理解为带有页面ID值作为文件位置Offset的海滩表的配置文件。此外,这里还将维护页面的空闲空间信息,因此,在插入时,我们可以直接找到要直接通过页面目录插入的页面。但是,这还带来了原子更新的问题,即页面的自由空间信息和插入的信息在原子操作中的数据。但是,由于这两页的操作,我很难确保这两页的两页在硬件级别上是原子的,因此我们需要一个附加的机制来检查是否存在当数据库重新启动时,这些未完成的写作。在恢复日志的章节时将提及。
每个页面都有一个页面(标题),该页面通常包含在标题中:
该页面需要包含,即如何解释和理解页面内容,您需要的所有信息必须存储在页面本身中。这样,即使您丢失了任何页面,也不会影响分析并使用任何其他页面。如果您将元数据存储存储在不同页面上的元数据数据分开,如果元数据页面丢失或损坏,则无法解析元组数据页面,则此自我包含的设计更适合灾难。恢复。
在页面内,我们有两种存储信息组信息的方法:
首先,让我们看一下面向存储方法设计的设计。首先,看一个非常糟糕的设计:假设所有元组的字节长度是相同的,那么实现方法相对简单。这样,我们可以直接跳到文件位置的位置到插入下一个元组。如果乌龟组的大小不同,则在此处插入的文件的定位将移动)。如果有一个新的元组插入,则根据元组的数量插入要插入的位置,然后更新头计数。当您需要删除元组时,假设元组2已删除:我们可以标记标记元组2所占用的空间是未使用的,而不是在元组后移动所有数据。但是,这带来了其他问题,即存储片段:
因此,这种设计不好,没有人会这样做。从基础上讲,插槽页面的设计(开槽页面):大多数数据库都采用了此设计。尽管细节有些不同,但大致是这样的结构。在开始或前面提到的页面中,请遵循两个存储结构
思考:我们可以在此页面上存储来自不同表的数据吗?实际上,没有人这样做。首先,附加的元数据记录每个元组的表,然后表数据访问通常是本地的,也就是说,我们访问表的某些数据。数据也可以稍后访问。将它们放在同一页面上更有效。如果一页中混合了不同表的数据,则丢失了此区域。
还有一个Yuanzu或Yuanzu的属性数据的大小超过一个页面,我们该怎么办?将要提及下一课。本课程还假定某个组的数据仅在单个单曲上存在页。
乌龟组实际上是一个字节序列。DBMS负责分析此字节序列。每个元组中都有一个头部,其中包括元数据数据,例如:
我们通常不将模式信息存储在每个组的头部上的模式信息(例如,数据是什么格式,数据是什么格式,是否可以为null等)。更少的数据导致更新和阅读效率降低。
然后,数据组数据,我们通常按照创建语句中的属性顺序存储数据组数据,大多数系统都这样做。某些系统将对属性进行排序,以便它可以更适合内存对齐(例如8- 字节对齐)以提高访问效率(内存和磁盘存储访问通常是可访问访问的访问)。
如何在DBMS的其他层下定位元组的数据?通常,所有元组将被分配一个唯一的ID。此ID将直接或间接页面ID信息和插槽(或偏移)信息,可以直接从ID中包含以查看页面ID和插槽信息,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接,间接。找到哪个目录或文件位置以查找文件定位的页面目录定位页面ID位移等等。在此方式,我们可以找到与页面相对应的文件以及通过页面ID查询页面目录的页面偏移和页面的偏移并在页面信息中找到乌龟组在储罐阵列中的位置,以阅读储罐的读数位置。
微信搜索“干货充满了张哈希”,请注意公共帐户,添加作者微信,每天一刷,轻松改善技术,并获得各种优惠
原始:https://juejin.cn/post/7098641020853682207