您的位置:首页 > 数据库

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

2016-04-23 19:04 288 查看

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

关于本教程

作者:InsZVA,浙江大学 软件工程系,也是第一次尝试写数据库,如有错误还望多多指正,写此篇文章也望有抛砖引玉的作用。

面向读者:有一定C语言基础。(其他知识会在教程中提到)

从SQL语句开始

对于数据库,我们最直观的概念或许就是在命令行中输入SQL语句来运行或者在PHP等语言中使用SQL语句进行增删改查。



我们这篇教程的目的就是做出像上图一样的数据库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语言的词法分析器了吧,这个词法分析器可以把输入的字符流转换成已经定义好的记号流,比如下图:



这里我们可以看到
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: