继手写jvm后,看到知乎有篇手写数据库的文章,一时兴起,打算摸鱼时间也用java撸一个。 一个多月零零星星写了点,以及其简单的方式实现了数据库建表和增删改查的功能,记录一下
一、数据库各模块
1.config: 数据库配置
2.connect: 数据库连接模块(暂时无视)
3.dbfile: 数据库文件模块
4.dbwindow: 控制台
5.engine: 数据库引擎
6.entity: 数据库实体(server,database,table ...)
7.executer: sql执行器
8.parser: sql解析器
9.tools: 公用工具集
各模块间打算使用门面模式对外提供接口
二、数据库功能介绍
目前数据库功能肥肠肥肠简单,只实现了以下功能:
1.控制台接收与展示:
接收用户输入的sql语句,并将返回结果通过自适应的表格进行展示(文字表格居中)
错误提示方面做得不完善,若sql命令输入错误,很可能不会收到报错提示,而是抛一堆异常给你
2.数据库sql解析:
将create、select、delete、insert、update等语句进行解析,以便数据库引擎能够执行。
目前解析功能还很粗糙,只能解析增删改查语句涉及的表名、字段名、筛选条件。筛选条件只能解析出被and、or、括号连接的判断条件的执行顺序,无法识别not,exist等关键字。而且sql关键字必须用小写输入
parser会根据优先级,将条件语句解析成一串指令队列,数据库引擎根据指令队列对所选数据进行筛选
3.数据库表格式的存储
完成了数据库表格式存储结构的设计(各引擎通用)
4.数据库引擎
定义了数据库引擎的接口,完成原始版本的数据库引擎basengine
5.数据库文件管理
用于读写数据库文件。默认路径写死在config模块里,以后改。受jvm .class字节码的启发,文件存放的均为16进制字节码,根据特定格式进行解析
二、basengine引擎
basenige即base engine(基础引擎),是我实现的第一个数据库引擎。以后将基于该引擎进行扩展,只是现在简陋得不忍直视:
1.插入
支持insert into [表名] (字段1,字段2,...,字段n) values (值1,值2,...,值n),(值1,值2,...,值n),...(值1,值2,...,值n)
或
insert into [表名] (字段1,字段2,...,字段n) values (值1,值2,...,值n)。
就是有点蠢,关键字和表名必须与括号隔开,不然解析会出错,插入时也不会对字段的唯一性做校验,所有插入的字段以字面量的形式进行存放。插入直接修改记录表大小,并将新的数据追加到文件尾。
表数据文件的结构相当简单,没有什么表空间、段、区等划分,只有基础信息、记录条数(4字节存储)和记录内容。记录内容以compact格式进行存储。
选择(单表)
没有索引,全表扫描!全是技巧,没有感情!
支持select * from [表名] where [条件句]
或 select [字段名列表] from [表名] where [条件句]
条件句优先级 括号 > or > and
只支持大于,小于,等于,大于等于,小于等于,不等于判断
删除
全表扫描。根据条件句筛选出未被删除的记录,修改原文件记录条数,覆写原文件记录区(嗯,好蠢)
修改
修改相当于删除+插入。扫描全表数据,找到符合条件的列,根据输入进行修改,最后覆写原文件记录区
update [表名] set [字段1] = [值1],[字段2] = [值2],...,[字段3] = [值3] where [条件句]
下一步,摸鱼学习b+树,给数据库创建个索引~