自己动手写数据库(一) 从SQL语句开始

自己动手写数据库(一) 从SQL语句开始

关于本教程

作者:InsZVA,浙江大学 软件工程系,也是第一次尝试写数据库,如有错误还望多多指正,写此篇文章也望有抛砖引玉的作用。
面向读者:有一定C语言基础。(其他知识会在教程中提到)

从SQL语句开始

对于数据库,我们最直观的概念或许就是在命令行中输入SQL语句来运行或者在PHP等语言中使用SQL语句进行增删改查。
1-1
我们这篇教程的目的就是做出像上图一样的数据库shell,支持语法错误定位,支持Create,Insert,Update,Delete,Drop等操作。

如何解析SQL

解析SQL,我们先想想SQL支持哪些语法呢,首先有一些关键字,像select之类,嗯,这个我用字符串匹配就可以解决,那么有个问题,create table
后面跟着的表名,他是一个由下划线、字母和数字组成的不定长的标识符,我该怎么识别呢?或许我可以识别到create和table之后,一直读读读,读到出现
空格、Tab、换行等分隔符为止?那么我该如何处理括号呢,有一定编程经验的可能会想到,使用栈(Stack)。对,这些都是ok的,然而如果遇到了and、or、not的
混合关系,优先级怎么处理呢?这些问题虽然使用朴素的读入字符串,判断都可以解决,但是对思维的要求很高,而且写出来的代码会是一堆if,这样出bug
很难调试,很难维护。
科学的姿势:使用状态机,状态机是什么呢,其实类似于把你的if语句存在了一个二维数组里面。我定义状态机DFA(x-(char)->y),x,y代表状态(State),char
代表如果当前状态是x,读入char的话就可以到达y状态。关于自动机,如何去从正则表达式生成自动机,以及有前人博客可以参考:vczh的教程

SQL语法分析

看完轮子哥的词法分析教程,大概可以写出一个SQL语言的词法分析器了吧,这个词法分析器可以把输入的字符流转换成已经定义好的记号流,比如下图:
1-2
这里我们可以看到select id,name from t1 where id=1这条语句已经被转换成了记号流,keyword、split、identical之类。这个时候,我们对记号流进行解析就容易多了,
因为我们知道用户输入的每个单词都是什么了。那么现在,我们就可以愉快的分析语法了,语法我们大概使用如下的方式来分析(以该条语句为例):第一个Token是select,交给
select处理器去处理,select处理器运行机制(读入Token时忽略空格符):
1. 读入第一个Token,如果不是select,报错
2. 读入第二个Token,如果不是identical,报错
3. 预读第三个Token,如果是,,那么进行第二步,否则第四步
4. 读入下一个Token,如果不是from,报错
5. 读入下一个Token,如果不是identical,报错
6. 预读下一个Token,如果还有,交给where处理器处理剩下的流没有的话,被查询的表是5中的identical,查询的字段是2.3.中的
类似于这样的步骤,我们知道了用户输入的字节流到底是做什么的,当然关于这部分有疑问的话,可以看看这篇文章:装配脑袋的教程

文中出现的截图,都来自Monkeydb2,monkeydb2是个人的一个小项目,目前有1w行go语言代码,关于monkeydb2的SQL解析部分在:SQL

发布了58 篇原创文章 · 获赞 23 · 访问量 10万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览