当前位置: 首页 > news >正文

【从零开始编写数据库系统】基于Python语言实现存储引擎

【从零开始编写数据库系统】基于Python语言实现存储引擎

  • 一、存储引擎简介
    • 1. 核心组件及功能
    • 2. 存储引擎的核心作用
  • 二、基于Python实现存储引擎代码结构
  • 三、存储系统原理图与数据流程分析
    • 系统原理图
    • 数据流程图
    • 详细解释与说明
      • 1. 系统架构分析
      • 2. 核心组件功能
        • 2.1 缓冲区管理器 (BufferPool)
        • 2.2 磁盘管理器 (DiskManager)
        • 2.3 页结构 (Page)
        • 2.4 记录序列化器 (RecordSerializer)
      • 3. 数据流程说明
      • 4. 设计特点与优势
      • 5. 潜在改进方向

一、存储引擎简介

数据库存储引擎,其核心功能是负责数据的物理存储、管理与高效访问,是数据库与底层存储介质(如磁盘)交互的核心模块。以下是其核心组件及整体作用的简介:

1. 核心组件及功能

  1. 页(Page):数据存储的基本单位
    page.py实现,以固定大小(4KB)为单位组织数据,分为页头(存储页ID、类型、空闲空间偏移量、校验和等元数据)和数据区(存储实际记录)。支持记录的添加、读取、逻辑删除(标记记录长度为负值)及校验和验证(确保数据完整性),是数据在磁盘和内存中的基本载体。

  2. 磁盘管理器(DiskManager):物理存储的直接管理者
    disk_manager.py实现,负责数据库文件的创建、打开、关闭,以及页的物理读写(通过页ID计算磁盘偏移量)。维护页缓存(减少磁盘IO)和空闲页集合(复用已释放的页),是内存数据与磁盘文件之间的桥梁。

  3. 缓冲区池(BufferPool):提升访问效率的缓存层
    buffer_manager.py实现,基于LRU(最近最少使用)策略管理内存中的页缓存,减少直接磁盘IO操作。跟踪“脏页”(内存中修改但未写入磁盘的页),负责缓存的命中、淘汰(缓存满时移除最久未使用的页)和刷盘(将脏页写入磁盘),是提升存储引擎性能的关键组件。

  4. 记录序列化器(RecordSerializer):数据格式的转换器
    record.py实现,负责将用户级记录(字典形式)与字节流互转,支持INT、VARCHAR、BOOL、FLOAT等数据类型。处理字符串截断(确保UTF-8字符完整性)、类型转换和格式校验,保证数据在页中按统一格式存储和解析。

2. 存储引擎的核心作用

  1. 数据持久化:通过页和磁盘管理器,将数据以结构化的方式存储在磁盘文件中,确保数据库重启后数据不丢失。
  2. 高效IO管理:通过缓冲区池的缓存机制,减少磁盘读写次数,平衡内存与磁盘的访问速度差异,提升数据访问效率。
  3. 数据完整性:通过页的校验和机制,验证数据在传输或存储过程中是否损坏,保证数据可靠性。
  4. 抽象存储接口:向上层提供统一的页操作、记录存取接口,屏蔽底层磁盘存储的细节(如文件偏移、格式转换等),简化上层模块(如查询引擎)的实现。

简言之,该存储引擎通过“页管理-磁盘交互-缓存优化-数据转换”的协同,实现了数据的可靠存储与高效访问,是数据库系统的“基石”。

二、基于Python实现存储引擎代码结构

在这里插入图片描述

  1. buffer_manager.py: 实现了缓冲区池管理器,用于缓存磁盘页,提高读写效率。
  2. disk_manager.py: 磁盘管理器,负责实际的文件I/O操作,包括页的分配、读取、写入和释放。
  3. page.py: 定义了页的数据结构,包括页头信息和记录存储方法。
  4. record.py: 记录序列化器,负责将记录序列化为字节流和反序列化。
  5. 首先,我们分析各个模块的功能和关系:1. RecordSerializer (record.py): 负责将记录(字典形式)与字节流之间进行转换。2.Page (page.py): 代表一个数据库页,可以存储多条记录。它负责管理页内的记录,包括添加记录、读取记录等。3. DiskManager (disk_manager.py): 负责管理数据库文件,包括分配页、读取页、写入页、释放页等操作。它使用文件系统来存储页。4. BufferPool (buffer_manager.py): 缓冲区池,缓存从磁盘读取的页,减少磁盘I/O。当需要读取页时,首先检查缓冲区,如果不存在则从磁盘读取并放入缓冲区。当页被修改时,标记为脏页,并在适当的时候写回磁盘。
    其次,代码之间的关系

    1.RecordSerializer 被上层模块(如表、索引等)使用,将记录序列化后,通过Page的add_record方法添加到页中。
    2.Page 通过DiskManager从磁盘读取或写入磁盘。
    3.BufferPool 在DiskManager之上,缓存页,提供更快的访问。
    但是注意:在提供的代码中,BufferPool直接使用DiskManager来读取页,而DiskManager自己也有一个页缓存(page_cache)。这在实际系统中可能不是这样设计的,因为通常磁盘管理器只负责直接磁盘I/O,而缓冲区管理则由缓冲区池负责。但这里DiskManager的缓存可能是为了减少实际文件I/O,而BufferPool则是为了在内存中缓存页以提供更快的访问。实际上,我们可以将DiskManager的缓存视为操作系统级别的缓存,而BufferPool是数据库级别的缓存。但为了简化,我们通常只在数据库级别做缓存。因此,这里DiskManager的缓存可能是不必要的,或者可以视为另一种形式的缓冲。
    4. 考虑到代码结构,我们绘制原理图如下:
    原理图(模块关系图):
    在这里插入图片描述
    1.RecordSerializer模块负责记录的序列化和反序列化,它与Page模块交互,因为Page中存储的是序列化后的记录。
    2.Page模块代表一个数据库页,它负责管理页内的记录存储布局。
    3.BufferPool模块是缓冲区池,它缓存了多个页,上层模块通过缓冲区池来获取页,减少了直接磁盘访问。
    4.DiskManager模块直接与操作系统文件系统交互,负责将页读写到数据库文件中。
    数据流程图(从记录到磁盘)
    1.插入记录:记录 -> RecordSerializer序列化 -> Page添加记录 -> Page标记为脏 -> BufferPool缓存页 -> 当刷脏时,BufferPool调用DiskManager写入磁盘。
    2.读取记录:BufferPool获取页(如果不在缓冲则从磁盘读取) -> Page读取记录 -> RecordSerializer反序列化 -> 得到记录。
    我们可以用两个流程图来描述读写过程。我们使用两个独立的流程图。
    写入记录的数据流程
    在这里插入图片描述
    1.记录首先被RecordSerializer序列化成字节数据。
    2.序列化后的数据被添加到Page中,Page会检查是否有足够空间。
    3.如果添加成功,Page被标记为脏。
    4.通过BufferPool的unpin_page方法标记页为脏(在取消固定时告诉缓冲区此页已被修改)。
    5.缓冲区池在适当的时机(如页淘汰或刷脏)将脏页通过DiskManager写入磁盘。
    读取记录的数据流程
    在这里插入图片描述
    读取过程
    1.请求记录时,首先通过BufferPool获取页。
    2.如果页在缓冲区中,直接获取;否则通过DiskManager从磁盘读取。
    3.从Page中获取记录的字节数据(通过get_records方法)。
    4.通过RecordSerializer反序列化字节数据得到记录字典。
    注意:在读取过程中,BufferPool会使用LRU策略缓存页,并且会记录命中次数和未命中次数用于统计。

三、存储系统原理图与数据流程分析

系统原理图

数据存储层
磁盘管理层
缓冲区管理层
应用层
http://www.dtcms.com/a/375525.html

相关文章:

  • 【Pywinauto库】8.3 pywinauto.findwindows 模块
  • 351章:Python Web爬虫入门:使用Requests和BeautifulSoup
  • 禅道,用域名访问之后不能登录的问题
  • Lodash-es 完整开发指南:ES模块化JavaScript工具库实战教程
  • 实践《数字图像处理》之图像方向性自适应阈值处理
  • 【Linux】系统部分——信号的概念和产生
  • android定制系统完全解除应用安装限制
  • 第2节-过滤表中的行-BETWEEN
  • OpenLayers数据源集成 -- 章节三:矢量要素图层详解
  • 基于AI Agent的智能决策支持系统正在逐步取代传统规则驱动的DSS
  • License 集成 Spring Gateway:解决 WebFlux 非阻塞与 Spring MVC Servlet 阻塞兼容问题
  • spark连接mongodb
  • ubuntu新增磁盘扩展LV卷
  • PowerApps 使用Xrm.Navigation.navigateTo无法打开CustomPage的问题
  • C/C++中基本数据类型在32位/64位系统下的大小
  • TensorFlow 和 PyTorch两大深度学习框架训练数据,并协作一个电商推荐系统
  • ceph scrub 参数
  • JavaWeb--day1--HTMLCSS
  • 全国连锁贸易公司数字化管理软件-优德普SAP零售行业解决方案
  • C++面向对象之继承
  • AI原生编程:智能系统自动扩展术
  • Wireshark TS | 接收数据超出接收窗口
  • 第一代:嵌入式本地状态(Flink 1.x)
  • 4.1-中间件之Redis
  • Django ModelForm:快速构建数据库表单
  • 【迭代】:本地高性能c++对话系统e2e_voice
  • SSE与Websocket、Http的关系
  • 蓓韵安禧DHA展现温和配方的藻油与鱼油营养特色
  • 基于UNet的视网膜血管分割系统
  • python函数和面向对象