实现一个微型数据库

实现一个微型数据库

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

自己写一个简单的数据库,原理大概有下面几点:

一、数据以文本形式保存

将所要保存的数据写入文本文件,这个文本文件就是数据库。

为了方便读取,数据必须分为记录,每一条记录的长度规定为等长。

举例:假定每条记录的长度是800字节,那么第5条记录的開始位置就在3200字节。

大多数的时候我们不知道某一条记录在第几个位置,仅仅知道主键的值。这时为了读取数据,能够一条条比对记录。可是这样做的效率太低。实际应用中,数据库往往採用B树格式存储数据

 

二、关于B树

要理解B树先须要理解二叉查找树

实现一个微型数据库

说二叉查找树是一种查找效率很高的数据结构,它有三个特点:

(1)每一个节点最多仅仅有两个子树。

(2)左子树都为小于父节点的值,右子树都为大于父节点的值。

(3)在n个节点中找到目标值,一般仅仅须要log(n)次比較。

 

二叉查找树的结构不适合数据库,由于他的查找效率与层数有关。越处在下层的数据,就须要越多次的比較。极端的情况下,n个数据须要n次比較才干找到目标值。对于数据库来说,每进入一层,就要从硬盘读取一次数据,这很致命,由于硬盘的读取时间远远大于数据处理时间,数据库读取硬盘的次数越少越好。

 

B树是对二叉查找树的改进。它的设计思想是,将相关数据尽量集中在一起,以便一次读取多个数据,降低硬盘操作次数。

实现一个微型数据库

B树的特点:

(1)一个节点能够容纳多个值。

(2)除非数据已经填满,否则不会添加�新的层,也就是说,B树追求“层”越少越好。

(3)子节点的值,与父节点中的值有严格的大小相应关系。一般来说,假设父节点有a个值,那么就有a+1个子节点。比方上图中,父节点有两个值(7和16),就应相应三个子节点,第一个子节点都是小于7的值,最后一个子节点都是大于16的值,中间的子节点就是7和16之间的值。

 

这样的数据结构很有利于降低读取硬盘的次数。假定一个节点能够容纳100个值,那么3层的B树能够容纳100万个数据,假设换成二叉查找树,则须要20层。假定操作系统一次读取一个节点,而且根节点保留在内存中,那么B树在100万个数据中查找目标值,仅仅须要读取两次硬盘。

 

三、索引

数据库以B树格式存储,仅仅攻克了依照“主键”查找数据的问题。假设想查找其它字段,就须要建立检索(index)。

所谓索引,就是以某个字段为keyword的B树文件,假定一张“雇员表”,包括了员工号(主键)和姓名两个字段,能够对姓名建立索引文件,该文件以B树格式对姓名进行存储,每一个姓名后面是其在数据库中的位置(即第几条记录)。查找姓名的时候,先从索引中找到相应的第几条记录,然后再从表格中读取。这样的索引查找方法,叫做“索引顺序存取方法”,缩写为ISAM。它已经有多种实现,仅仅要使用这些代码库,就能自己写一个最简单的数据库。

 

四、高级功能

部署了最主要的数据存取(包含索引)以后,还能够实现一些高级功能。

(1)SQL语言是数据库通用操作语言,所以须要一个SQL解析器,将SQL命令解析为相应的ISAM操作。

(2)数据库连接(join)是指数据库的两张表通过“外键”,建立连接关系。你须要对这样的操作进行优化。

(3)数据库事务(transaction)是指批量进行一系列数据库操作,仅仅要有一步不成功,整个操作都不成功。所以须要有一个“操作日志”,以便失败时对操作进行回滚。

(4)备份机制:保存数据库的副本。

(5)远程操作:使得用户能够在不同的机器上,通过TCP/IP协议操作数据库。

 

 

 

关于数据库原理思考Q&A:

1、设计一个支持TB级别数据的数据库,并且要能支持高效的区间查询(范围查询).怎么办?

解答:首先要明白,并非全部的字段都能够做区间查询.比方对于一个员工,性别就没有所谓的区间查询,而工资是能够做区间查询的,比如查询工资大于a元而小于b元的员工。

 

我们将须要做区间查询的字段相应的字段值提取出来作为keyword构建一棵B+树,同一时候保存其相应记录的索引。B+树会对keyword排序,这样我们就能够进行高效的插入,搜索和删除等操作。我们给定一个查询区间,在B+树中找到相应区间開始的结点仅仅须要O(h)的时间,当中h是树高,一般来说都非常小。叶子结点保存着记录的索引,并且是按keyword(字段值)排好序的。当我们找到了相应区间開始的叶子结点,再依次从其下一个块中找到相应数量的记录,直到查询区间右端(即最大值)为止.这一步的时间复杂度由其区间中元素数量决定.

 

避免使用将数据保存在内部结点的树(B+树将数据都保存在叶子结点),这样会导致遍历树的开销过大(由于树并很驻内存)。

实现一个微型数据库

如果这棵B+树上相应的数字表示工资,单位千元。员工相应的工资数据, 事实上就都保存在叶子结点上,内部结点和根结点保存的仅仅是其子结点数据的最大值。 这里如果每一个叶子结点上的工资值所在的那条记录索引并没有画出来。OK, 如今我们要查询工资大于25k小于60k的员工记录。

区间的開始值是25,我们訪问根结点,发现25小于59,于是向左子结点走。 然后继续。发现25大于15且小于44,于是向当中间子结点走。 最后在叶子结点查找到第一个大于25的值是37。接下来再依次地将结点内部的其它值 (44),和它下一个叶子结点的值(51,59)相应的记录返回(不再往下查找, 由于以下的数已经大于60)。这样一来,即实现了高效的区间查询。

 

 

 

 

 

 

 

 

部分内容来自点击打开链接,兴许依旧会不断更新完好。

 

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/118711.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 解决Pycharm无法显示matplotlib绘图问题(ubuntu环境)「建议收藏」

    解决Pycharm无法显示matplotlib绘图问题(ubuntu环境)「建议收藏」1.首先,确保环境(虚拟环境)中已经安装了matplotlib模块首先切换到虚拟环境中,然后安装安装命令:condainstallmatplotlib2.确定你的pycharm使用的环境是你的虚拟环境(1)在pycharm中添加虚拟环境pycharm默认使用的环境可能并不是你想用的虚拟环境:如图在file->settings里面可以找到配置虚拟环境的窗口。点1,…

    2022年8月28日
    2
  • python获取linux环境变量_linux如何设置环境变量

    python获取linux环境变量_linux如何设置环境变量Python对环境变量的访问不能准确反映操作系统对流程环境的看法.os.getenv和os.environ在特定情况下不能正常运行.有没有办法正确地获得运行过程的环境?为了演示我的意思,采用两个大致相同的程序(C中的第一个,python中的另一个):#include#include#includeintmain(intargc,char*argv[]){char*env;for(;…

    2022年9月28日
    0
  • mysql查询表的索引_MySQL查看表索引[通俗易懂]

    mysql查询表的索引_MySQL查看表索引[通俗易懂]mysql>showindexfromtblname;mysql>showkeysfromtblname;·Table表的名称。·Non_unique如果索引不能包括重复词,则为0。如果可以,则为1。·Key_name索引的名称。·Seq_in_index索引中的列序列号,从1开始。·Column_name列名称。·Collation列以什么方式存储在索引中…

    2022年9月9日
    0
  • shift键粘滞了怎么办_5shift后门清免疫

    shift键粘滞了怎么办_5shift后门清免疫1.简介沾滞键的目的是为了帮助那些按键有困难的人设计的

    2022年9月17日
    0
  • 高德定位SDK_高德地图api使用教程

    高德定位SDK_高德地图api使用教程1.LocationManagerProxy获取当前Context创建一个LocationManagerProxy变量mAMapLocManager=LocationManagerProx

    2022年8月1日
    9
  • 背包九讲—-整理+例题[通俗易懂]

    背包九讲—-整理+例题[通俗易懂]背包九讲类型汇总:1.01背包问题2.完全背包问题3.多重背包问题4.混合背包问题5.二维费用的背包问题6.分组背包问题7.背包问题求方案数8.求背包问题的方案9.有依赖的背包问题注:以下所有题目来源于ACwing题库,链接:https://www.acwing.com/problem/这里每个类型基本都是具体题目+自己的一些体会+代码,背包九讲的理论以及解析证明之类的…

    2022年4月19日
    47

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号