作业系列 - 尝试编写SQL数据库(三)

按照之前的想法,似乎应该先做语言处理层,再做内存,再做文件存储,而在实验过程中突然发现如果没有做文件存储的话,设计内存中的数据库很难写,或者担心写了和将来的文件存储层互相排斥,既然是尝试编写SQL数据库,就写一个全套的吧,在这里先写下自己对数据库文件存储格式的设想。

因为数据库涉及很多的权限要求,因此我将数据库的前32个byte用于描叙权限,我对权限的设想是这样的,数据库和用户在增删改查等各方面都有一个权限等级,如果用户在某一方面的权限等级低于数据库该方面的权限等级,就无法进行该项操作。在紧随其后的一个long,用来保存碎片链表,之后用来保存数据库的字段名,之后用来表示表,之后留出8个long值用来保存其它(如可能用到的check约束,高权限用户给低权限用户授权的记录)。

以上为数据库文件的文件头,它的大小固定,初始默认值为0.用表格列举如下:

用来保存权限(32byte)碎片链表首地址(long)字段名首地址表元素首地址包含前面三个共八个long值保存其它可能使用的功能...
也就是说,这个数据库是使用链表的形式来保存的,链表节点头的格式是固定的:

节点大小【长度】(int)节点状态(byte)下一节点位置(long)上一节点位置(long)

【2016-11-12修改,由于byte【int】所以节点长度为long没有意义】数据库使用随机文件访问的方式来进行操作(RandomAccessFile)这样可以在数据库中随时进行跳转。状态量用来保存改链表节点的使用状况,默认0代表未使用,1代表可操作,在后来的拓展中,如果需要加入多线程安全方面的内容,这个字节或许需要更多的值,比如2代表写禁止,3代表读禁止等等。

数据库的其他元素都是在这个的基础上进行设计,比如对于表内的数据,可以增加右元素地址来访问下一个字段的值,在这片内存被废弃之后(比如进行了删除操作),数据库应当做一个更改得优先级选择,首先应当令byte的值为0,表示内存已废弃,之后将该节点按节点大小插入到碎片链表中(在插入的过程中检测相同大小的节点中是否存在已经存在该位置,即是否存在某一个节点的next值为本节点的地址,一个比较好的思路是每一个新的碎片都插入到相同大小碎片的最后一个)。之后更改废弃节点的上一个节点的下一个节点位置为该废弃节点的下一个节点的位置,废弃节点的下一节点的上一节点的位置为废弃节点的上一节点的位置(有点绕口令了,就是链表删除操作要做的工作)。之所以要按照这个顺序,是为了万一在进行某一个操作的过程中,程序突然崩溃了,导致的断链或者碎片的产生。考虑到这种情况在遍历链表的时候,如果发现某一节点的下一节点状态值为0,则应该同上进行碎片回收操作,在遍历过程中应当不断的检测上一节点值是否合理。特别需要注意的是:即使遍历到某一元素的状态值为0,他也可能拥有下一个元素的。
在申请空间的时候应当优先考虑从碎片链表中选取,实际上,碎片链表完全可以设计为碎片树以减少插入、查询的耗时(直接把上下节点位置转换成左右子树)。可以对碎片树中的碎片进行合并处理具体操作为:遍历碎片,检查碎片的下一个节点的状态值是否为0,为零的话可以合并,不为零则不可以合并,注意不要越过文件尾。

这种设计的数据库在理论上是不断增大的,但是由于增设了碎片处理,数据库应该是无碎片或者轻碎片的。在使用碎皮那链表中的内存是,应当注意不要修改碎片的节点大小值,如果在必要情况下要将一个大的碎片内存截断为两个较小的碎片内存,最好保持两个碎片的大小几乎相等,最基本的要求也是碎片的大小比节点头大一个byte(布尔类型值等可以用到)

暂时设想如此,还未付诸行动。具体代码完成后会同步更新到git上面,希望大家可以提出意见,谢谢大家。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值