看了这个大学本科生用三个星期写的数据库,

那家医院治疗白癜风好 http://pf.39.net/bdfyy/bjzkbdfyy/

哈喽,大家好,我是开源君,一个资深的互联网玩家,致力于为大家分享各领域优质开源项目。

今天给大家分享的项目是一位来自东北大学叫蓝一潇的同学使用Python写的数据库OdysseyDB,这是一个轻量级文件键值对数据库。

项目灵感

有一天,蓝一潇同学突发奇想,要自己写一个数据库。在这个开源的时代,现成的数据库数不胜数,为什么非要自己写一个呢?这来源于有一个比较特殊的项目需求:让同一份Python代码在不同环境下无缝衔接,接续运行。

要满足这个需求,首先考虑使用Sqlite记录运行时结果,接续运行时将结果读出赋给变量;但出于Sqlite是关系型数据库,程序运行的中间变量恰恰又保存在许多不同的数据类型中,虽然Sqlite提供了Blob类型可以记录二进制数据,但难免会存在一些格格不入的问题,还需要手动将数据序列化。最好的方式应该是将数据保存在键值对里面,因此想到了之前经常使用的Redis。而Redis数据库的部署和迁移较为繁琐,需要开启服务端口,这对需要在安卓Termux和一些嵌入式设备上运行项目非常不友好。

对于记录中间变量,在Python中,有一个妥协的办法:直接使用Pickle把字典序列化保存在本地,接续运行时再从本地加载。但是这不太优雅,而且它不支持查看历史更改记录,不提供日志,操作也较为复杂。

于是,他找到一种优雅的办法来接续记录这些运行时数据,就是按照自己对项目需求优雅的理解,自己写一个键值对数据库,自给自足,丰衣足食。

开发历程

蓝一潇同学本科的研究方向并不是数据库,在短期内从零开始写一个数据库并不是一件容易的事情,最初他给自己的目标是较短的时间先开发出一个版本,能用就行。同时,我想把它做成一个PyPI的Package,既然是一个Package,那么就尽可能不要引用第三方库;那么要求就是仅使用Python3提供的标准库来完成这个数据库。他给自己设定的开发周期是三个星期。

在项目开始之前,需要给这个项目一个命名。他给它起了一个名字叫做OdysseyDB,一方面纪念库布里克的经典科幻电影《:ASpaceOdyssey》,一方面寓意这个数据库就能像宇宙飞船一样在不同的空间进行灵活的迁移。

借鉴Sqlite3的文件结构,他给OdysseyDB设计了头部+数据页的结构,并初步定下了数据的存取方式——索引寻址+页面偏移+页内偏移。有了这些基本的设定,就开始了OdysseyDB数据库的开发。

在开发过程中,他遇到了很多问题。第一个问题是,需要设计一种高效的索引机制,索引在OdysseyDB中的作用是保存每一个存入的键对应的值所保存在文件中的偏移量,而不是值本身;例如B树或者是哈希表都是比较理想的索引方式,但在有限的三星期之内,设计一个高效的索引机制可能会耗费大量的时间。于是他灵机一动,直接先使用Python提供的字典作为索引,在后续的升级中,逐渐摆脱对字典的依赖。

每一个存在文件中的键对应的值的数据块会分为几个域,包括修改时间、修改者、数据长度、过期时间、该键上一个值的指针,以及这个以被二进制编码的值本身。

在他的构思中,将整个项目分为四个层次:底层、会话层、Handler层、用户API层。底层封装了所有对于文件的操作,皆为函数,不涉及类;会话层开始使用类,维护了一个文件描述符db,对底层的文件操作进行了一个较为明确的封装;Handler层接受用户API层传下的数据和请求,并封装处理(如进行序列化,长度计算,偏移量计算),进而交付会话层进行文件操作;用户API层则为用户提供了一个相当便捷的Odyssey类,它实现了几乎所有Python字典的特性,以及部分RedisAPI。

项目总结

整个开发过程耗时约三个星期,在这三个星期里,他还经历了毕业答辩、之前的论文被录用要补实验等一系列琐碎的事情,他就用事情的缝隙来完成OdysseyDB;在他的任务排序中,开发OdysseyDB所给他的喜悦是第一位的,会每天习惯性的打开电脑写,常常在天亮之后才上床睡觉。最终,完成了这个OdysseyDB的1.1.0版本,并迫不及待的将它上发布到了PyPI。在这里推荐OdysseyDB,欢迎大家在有同样的需求时尝试一下;在这里总结了一下使用它的理由:

可迁移:类似Sqlite3,即开即用,每一个数据库都是一个文件,简单的复制粘贴即可完成数据库的跨平台迁移,但有别于Sqlite的关系型数据库,OdysseyDB为键值对数据库。可以轻易在不同环境下部署,在不同环境下接续运行同一程序时可动态载入持久化的运行时变量,支持热插拔,记录变量历史值和日志。不需要开启端口,但可以同时服务多个进程,并满足数据库的ACID特性。便捷:极易上手。实例化后的Odyssey对象提供了几乎所有字典的特性,可以作为一个字典使用,区别是该字典会实时持久化在文件中,记录运行状态和历史更新记录。与此同时,Odyssey还提供类似Redis的API,方便开发。灵活:有别于Redis只能记录list、str和int等有限数据结构,OdysseyDB底层将对象字节流序列化且对用户透明,几乎可以记录任何的Python数据结构(包括自定义的那些),为开发者提供极大便利。详细:可以记录每一个变量的历史修改日期、历史值,提供日志。项目说明

一个简短的使用说明,更详细的readMe文档。

安装:pipinstallOdysseyDB#(python=3.0)实例化一个Odyssey数据库importOdysseydb=Odyssey.connect(test.db)#如果没有该数据库,则将创建一个空数据库或者:fromOdysseyimportOdysseydb=Odyssey(test.db)或者:fromOdysseyimportOdysseywithOdyssey(test.db)asdb:pass对键值对的存取可以使用简单的.set.get方法:db.set(hello,Odyssey)print(db.get(hello))或db[hello]=Odysseyprint(db[hello])键的删除以下三种方法等价:deldb[hello]db.del_key(hello)db.pop(hello)#会返回被删除的键的最后一个值

更多OdysseyDB项目使用方式,请复制下方开源项目地址研究学习

开源项目


转载请注明:http://www.budalagongg.com/wxbz/542269.html


当前时间: