自己动手写数据库(一) 从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

  • 8
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值