从0开始学习数据库(持续更新)

news2024/11/26 12:33:09

一个数据库最重要的部分是什么?
关系型数据库mysql有着四大特性,原子性,隔离性,一致性,持久性。
kv数据库有着原子性,持久性,弱一致性。
可见,不管数据库的存储引擎是什么,其根本大概就是保证原子性,持久性和一致性的同时,通过一些优化提高数据库的查询效率。
以postgreSQL为例,系统结构包括链接管理,编译执行系统,存储管理系统,事务系统。不可否认这些都很重要,但我认为最重要的应当是存储管理和事务。
目前,我认为,一个数据库的核心实现在于事务和持久化,以及后续的一系列操作的优化。
因此,重点是首先解决事务和持久化。
从github上寻找数据库,分析源码,看他们是如何实现事务和持久化,就是本文的重点了。

skiplist-cpp项目

一个基于跳表的存储kv引擎:https://github.com/youngyangyang04/Skiplist-CPP
这个是我第一个接触的存储引擎,非常简单的一个项目,核心的实现只有两个cpp文件,这里就不多介绍了,ReadMe写的很清楚。
提供增删查三个接口,
没有进行事务处理,原子性是通过对方法加锁的方式比较粗暴的实现的。
持久化是直接kv转string以文本的方式通过fstream.writh保存字符串在本地。直接通过readline的方式进行本地存取,我觉得这不是一个理想的方式。

BeetleDB项目

一个简单的数据库实现:https://github.com/chenbjin/BeetleDB
作者的码风挺好,但是没有文档,只能自己扒源码慢慢看,算是一个比较全的流程吧,从sql解析,到数据库,表这些的创建,再到索引的建立,增上改查和数据持久化。
尽管我关注的是事务和持久化,但由于该项目的文档比较简陋,所以简单梳理一下项目结构:
在这里插入图片描述
大概介绍一下,我将项目主要分为三部分:1.业务,2.存储,3.索引

  1. 业务部分:主要由Interpreter,SQLStatement,CatalogManager和API部分进行管理。
  2. 索引部分:主要由IndexManager,BPlusTree进行管理。
  3. 存储部分:主要由RecoderManager,BufferManager,fileHandle,fileInfo,BlockHandle和BlockInfo进行管理。

BeetleDB是单线程,没有事务管理的数据库,因此我们对它的学习重点是在持久化和索引。

持久化

持久化值得说一说,BeetleDB在持久化上做的工作就比上面的skiplist-cpp项目要多一些,它将文件保存为下图这样的二进制文件,一个表中的数据保存在一个文件中,一个文件由多个block组成,每个block保存着逻辑相邻block的信息以及block本身保存的数据,这样做的好处就是可以直接通过文件指针跳到对应的存储单元中进行本地修改,减少遍历文件的花费,这一手我觉得是可以参考学习的。
在这里插入图片描述
给出核心代码(部分)BlockInfo::WriteInfo()

path += file_->get_db_name() + "/" + file_->get_file_name();
if (file_->get_type() == FORMAT_INDEX) path += ".index";
else path += ".records";

ofstream ofs(path, ios::binary);
ofs.seekp(block_num_*4*1024);
ofs.write(data_,4*1024);
ofs.close();

这里的代码就是关于写入一个file中的block的方法了,很清晰,先通过path找到文件,用二进制打开,然后用seekp移动文件指针到对应的block上,直接write一个block的数据就好了。read的方法同理,把write换成read即可。
这些写入的block都是在内存中维护的,因此当要对一个内存中的block持久化的时候,直接调用对应blockInfo对象的write方法即可。
至于如何维护内存中的blockInfo对象信息,可以结合上面的项目结构去源码里看,个人感觉还蛮清晰的。
简单提一下关于crud的操作,业务逻辑主要集中在RecordManager中,其实本质还是现在内存中找,找不到就去磁盘一个block一个block的找。

索引

建立在一个表column上的index是通过B+树进行维护的。
其实就是常见的B+树操作,注意一点就是,这里b+树的一个节点可以保存一个block的信息,里面的key顺序存储,在查找的时候有二分和顺序两种选择,阈值源码中定义的是20。

感觉叶子节点比较重要:BPlusTreeNode::GetKeys(), BPlusTreeNode::GetValues(), BPlusTreeNode::GetNextLeaf()

TKey BPlusTreeNode::GetKeys(int index)
{
	TKey k(tree_->GetIndex()->get_key_type(), tree_->GetIndex()->get_key_len());
	int base = 12;
	int lenr = 4 + tree_->GetIndex()->get_key_len();
	memcpy(k.get_key(), &buffer_[base + index * lenr+4], tree_->GetIndex()->get_key_len());
	return k;
}
int BPlusTreeNode::GetValues(int index)
{
	int base = 12;
	int lenR = 4 + tree_->GetIndex()->get_key_len();
	return *((int*)(&buffer_[base + index*lenR]));
}
int BPlusTreeNode::GetNextLeaf()
{
	int base = 12;
	int lenR = 4 + tree_->GetIndex()->get_key_len();
	return *((int*)(&buffer_[base + tree_->get_degree()*lenR]));
}

这里的buffer就是block对应的那一块数据,索引文件的block相比起普通文件的block,每行多了4个字节的空间,从BPlusTreeNode的set方法中就可以看出来,一个block组成为nodetype,count,parent,多至少4字节的空间来保存int型变量。

BettleDB数据库是一个小型的单线程数据库,没有事务管理,但提供了一个相比起skiplist-cpp更好的持久化方法,和索引示例。这也是我认为BettleDB最重要的部分之一。

LevelDB

源码:https://github.com/messixukejia/leveldb
一个开源的优秀的kv NoSQL。码风很好,网上的资料也有,因此可以尝试入门学习。
可以学习它的事务,存储,和sql优化方案。

可以采用自顶向下和自底向上结合的方法学习,
先宏观了解levelDB的架构和模块, 了解整体项目内容, 再从文件存取开始向上迭代.
目前正在学习中…

参考几个源码解析的文章:

  • https://www.zhihu.com/column/c_1282795241104465920
  • https://blog.csdn.net/sparkliang/category_1342001.html
  • https://zhuanlan.zhihu.com/p/80684560

levelDB涉及到LSM tree:

  • https://zhuanlan.zhihu.com/p/181498475

PostgreSQL

源码:https://github.com/postgres
一个开源的经典关系型数据库。码风较好,源码也容易获得,可以尝试继续学习。

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

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

相关文章

LeetCode_递归_中等_138.复制带随机指针的链表

目录 1.题目2.思路3.代码实现(Java) 1.题目 给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random,该指针可以指向链表中的任何节点或空节点。 构造这个链表的深拷贝。 深拷贝应该正好由 n 个全新节点组成&#…

vector源码解析及扩容优化

一、vector源码解析 没有任何一个东西可以在原地扩充,因为要了一块内存后,后面这块内存有可能被使用了,或者能不能用也不知道。链表可以保留原有节点,再将指针指向别处开辟的新内存,但这个也不算原地扩充。 对于vecto…

不需要等待列表,也不用魔法上网的Claude,能否比肩ChatGPT?

近期,国外Anthropic公司发布了Claude聊天机器人,堪比ChatGPT的最大竞争对手。一经推出,市场上就经常拿它俩来对比,因为推出Claude产品的Anthropic 公司是由多位前OpenAI前员工组成,两家公司,以及他们推出的…

ssm框架之SpringMVC:乱码问题

一种修改tomcat配置文件 如果tomcat乱码修改Tomcat的conf的server.xml文件加上 URIEncoding“UTF-8” 添加一个URIEncoding“UTF-8” tomcat 如果7.0 不这样设置,无论get还是post后台都显示乱码。tomcat如果是8.0版本,只有post后台显示是乱码 一种过滤…

Redis进阶

主要内容 Redis持久化Redis主从Redis哨兵Redis分片集群 Redis持久化 Redis有两种持久化的方案: RDB持久化AOF持久化 1. RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所…

HTML基本知识与常用标签的使用以及实现一个HTML版本个人简历

文章目录 HTML1. HTML结构1.1 认识标签1.1.2 HTML文件结构 2. HTML常见标签2.1 注释标签2.2 标题标签2.3 段落标签2.4 换行标签2.5 格式化标签2.6 图片标签2.7 超链接标签2.8 表格标签2.9 列表标签2.10 表单标签2.11 label 标签2.12 select 标签2.13 textarea 标签2.14 无语义标…

[架构之路-200]- 性能需求与性能分析:影响性能的主要因素

目录 前言:关于性能的几点说明 第一章 性能需求:提出各种性能指标 1.1 可靠性或可用性: stablity 1.2 处理能力或效率: Performance 1.2.1 指标是吞吐率 1.2.2 指标是响应时间: 1.2.3 指标是资源利用率 1.3 高并发性 1.…

FreeRTOS开启任务调度函数xPortStartScheduler详解

在FreeRTOS中,创建完任务后需要调用vTaskStartScheduler开启调度器,在这个函数主要就是创建空闲任务然后调用xPortStartScheduler函数开启任务的调度,本篇文章就以Cortex-M7为例来分析一下这个函数具体做了什么事,并深入理解其中的…

文献阅读:A Lite Distributed Semantic Communication System for Internet of Things

目录 动机:为什么作者想要解决这个问题?贡献:作者在这篇论文中完成了什么工作(创新点)?规划:他们如何完成工作?理由:通过什么实验验证它们的工作结果自己的看法 动机:为什么作者想要…

Python遍历大量表格文件并筛选出表格内数据缺失率低的文件

本文介绍基于Python语言,针对一个文件夹下大量的Excel表格文件,基于其中每一个文件内、某一列数据的特征,对其加以筛选,并将符合要求与不符合要求的文件分别复制到另外两个新的文件夹中的方法。 首先,我们来明确一下本…

【Linux】多线程 --- POSIX信号量+懒汉模式的线程池+其他常见锁

Linux system sprinkle flowers 文章目录 一、POSIX信号量1.阻塞队列实现的生产消费模型代码不足的地方(无法事前得知临界资源的就绪状态)2.信号量的理解3.初步看一下信号量的操作接口4.环形队列实现的生产消费模型5.环形队列的代码编写(维持…

百度将凭借人工智能改变游戏规则并实现盈利?

来源:猛兽财经 作者:猛兽财经 稳健的财务业绩 在2022年第四季度,百度(BIDU)的收入为48亿美元(331亿人民币),比分析师预测的高出了1.72亿美元,但同比下降了约8%。从细分业务来看,百度…

Android:你真的会用Toast吗(介绍安卓好看简约的Toast快速解锁方法)

目录 概要 开源库地址 如何使用 1、首先我们现在根目录下的build.gradle中添加以下依赖 2、然后我们在我们的模块目录(通常是app)下的build.gradle中添加以下依赖 3、 然后这一步是可选的,你可以在你的app模块下任意位置,添加以下…

ANR原理篇 - ANR弹框是如何显示出来的

系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 文章目录 系列文章目录前言一、ANR弹框是如何显示流程1.1 找到弹框对应类1.2 查找AppNotRespondingDialog引用…

Python程序员职业现状分析,想提高竞争力,就要做到这六点

现今程序员群体数量已经高达几百万,学历和收入双高,月薪普遍过万。今天,我们就围绕90后程序员人群分析、职业现状、Python程序员分析等,进行较为全面的报告分析和观点论述。 一、程序员人群分析 人数规模上:截当前程…

javaweb系列-JSON对象、BOM对象、DOM对象

1.5.1.3 JSON对象 在 JavaScript 中自定义对象特别简单&#xff0c;其语法格式如下&#xff1a; <body><script>//自定义对象var user {name: "tom",age: 20,gendar: "male",eat: function () { //函数alert("吃饭啦");}};aler…

Xcode多个子工程结合联编开发SDK

Xcode版本&#xff1a;Version 14.3 (14E222b) 这是啥&#xff1f; chat&#xff1a; Xcode 多个子工程结合联编可以用于开发 SDK&#xff0c;这种开发方法是在一个主工程中包含多个子工程&#xff0c;每个子工程代表 SDK 中不同的模块&#xff0c;每个子工程都可以独立编译。…

AutoDL平台租借GPU详解

AutoDL平台租借GPU详解&#xff08;2023年&#xff09; 一、AutoDL租用GPU 1.1 创建实例 首先进入AutoDL官网&#xff1a;AutoDL-品质GPU租用平台-租GPU就上AutoDL进行学生注册登录&#xff08;学生有优惠&#xff09;点击右上角的控制台&#xff0c;进入AutoDL的主页&#…

人工智能应用--深度学习原理与实战--神经网络的工作原理

机器学习是将输入(比如图像)映射到目标(比如标签“猫”)&#xff0c;并建立映射规则(即模型)。在深度学习中&#xff0c;神经网络通过一系列数据变换层来实现这种输入到目标的映射&#xff0c;本章节我们具体来看这种学习过程是如何实现的。 学习内容 1、理解层(Layer)及权重(…

Java调用C#

由于项目采用Hybrid热更&#xff0c;走纯C#开发&#xff0c;目前战斗由客户端到服务端&#xff08;客户端提供dll&#xff09;&#xff0c;服务端负责调用&#xff0c;故需要走Java 调C# dll逻辑。 1、JNI&#xff1a;不支持泛型&#xff08;pb&#xff09;没法转C成功 2、JN…