如何用5000行JS撸一个关系型数据库

首先声明,我不是标题党,我真的是用5000行左右的JS实现了一个轻量级的关系型数据库JSDB,核心是一个SQL编译器,支持增删改查。

 

源代码放到github上了:https://github.com/lavezhang/jsdb

如果你需要修改程序引入新的特性,请严格遵守GPL协议。

如果转发此文,请注明来源。

 

体验页面

 

SQL范例

 

前言


工作太忙,好久没写这种长文章了,难得今年国庆超长,又不便外出,这才有时间“不务正业”。

为什么要用一周的时间写这么个玩意儿?看起来也没什么用处,毕竟,没有哪个系统需要在浏览器中跑一个关系型数据库

如果要搞一个"年度最无用项目"的颁奖,估计JSDB榜上有名。

 

我一直有一个梦想,要研发一款咱们中国人自己的列式存储分布式数据库!(此处应有掌声^_^)

古人讲,不积跬步无以至千里,JSDB就算探索数据库自研的一个开端吧。

为什么用TypeScript?因为coding效率非常高,跟Python差不多,而且有浏览器就能运行,非常方便,很适合做技术预研,正式开发时再改为C或Rust。


如文章开头所言,JSDB的核心是一个SQL编译器,准确地说,是解释器。学习过《编译原理》的同学,对这个不会陌生。

解释器也是属于编译器的范畴,所以,后面仍然会沿用“SQL编译器”的说法。


概述


按照执行顺序,JSDB的代码由四个部分构成:

1、词法分析,得到 token 列表。参见GitHub源代码,SqlLexer.ts 文件,基于状态机实现,详见 lex_state_flow.xlsx 文件。

2、语法语义分析,得到抽象语法数。参见 SqlParser.ts 文件,自上而下解析,这是行数最多的一个文件。

3、对抽象语法树的执行。参见SqlDatabase.ts文件,以及ast目录下的几十个语法节点的compute(ctx)方法。

4、单元测试和应用范例。test目录和test.html文件里运行着所有的单元测试,index.html文件就是文章开头的体验页面,语法高亮功能基于第三方组件codemirror实现,在 static/codemirror 目录里。


JSDB确实是一个关系型数据库,参照SQL92标准实现,但它并不完整,只实现了最核心的一小部分功能,可以满足日常基本需求。主要特性有:

01、create table 语句

02、insert 语句

03、update 语句

04、delete 语句

05、select 语句,含:distinct / from / join / left join / where / group by / having / order by / limit

06、算数运算符:+、-、*、/、%

07、关系运算符:>、>=、<、<=、=、<>

08、条件运算符:and、or、not

09、其它操作符:like、not like、is null、is not null、between

10、动态占位符:?

11、标准函数,目前只实现了:ifnull、len、substr、substring、instr、concat。
如果需要增加新的标准函数,可以在SqlContext类的构造函数中实现,所有的标准函数都注册到SqlContext.standardFunctions字段中。


尚未实现的重要特性有:

1、with / sub query / exists / alter / truncate 等

2、数据存储。一直在内存中运行,大家可以修改程序,写入浏览器localStorage中。

3、事务。这个需要事务日志来实现,以后再搞,不过在内存中模拟一个,问题也不大。

4、并发锁。JS是单线程,没有真正的并发,有了一个不用实现它的好理由。

5、其它功能。详见大学时的《数据库原理》。

 

如果大家多多点赞,我就把它实现得更加完整。^_^

 

本文针对编译器和数据库的入门读者,写了很多小白的内容,高手请飘过。

 

第一章 词法分析

 

关于词法分析,程序本身并不难。无论何种编程语言,它的词法分析模块一般都不超过300行,有些甚至只有几十行。

很多人喜欢用 lex/yacc/antr 之类的工具来自动生成,我不喜欢,我就是喜欢手撸的感觉。

 

词法分析就是要识别源代码中的一个个token,一般包括:关键字、标识符、字符串、数值、布尔值、空值、运算符、操作符、分隔符。

例如,一条SQL语句:

select name, (total_score / 4) as avg_score from student where id = '010123'

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfxxz.html