如何实现一个SQL解析器

?作者:vivo 互联网搜索团队- Deng Jie
一、背景随着技术的不断的发展,在大数据领域出现了越来越多的技术框架 。而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进行数据查询 。SQL作为一个学习成本很低的语言,支持SQL进行数据查询可以降低用户使用大数据的门槛 , 让更多的用户能够使用大数据 。
本篇文章主要介绍如何实现一个SQL解析器来应用的业务当中 , 同时结合具体的案例来介绍SQL解析器的实践过程 。
二、为什么需要SQL解析器?在设计项目系统架构时,我们通常会做一些技术调研 。我们会去考虑为什么需要SQL解析器?怎么判断选择的 SQL 解析器可以满足当前的技术要求?
2.1 传统的SQL查询传统的SQL查询,依赖完整的数据库协议 。比如数据存储在MySQL、Oracle等关系型数据库中,有标准的SQL语法 。我们可以通过不同的SQL语句来实现业务需求,如下图所示:
如何实现一个SQL解析器

文章插图
但是,在处理海量数据的时候,关系型数据库是难以满足实际的业务需求的,我们需要借助大数据生态圈的技术组件来解决实际的业务需求 。
2.2 实际应用场景在使用大数据生态圈的技术组件时,有些技术组件是自带SQL的,比如Hive、Spark、Flink等;而有些技术组件本身是不带SQL的,比如Kafka、HBase 。下面,我们可以通过对比不带SQL和使用SQL解析器后的场景,如下图所示:
如何实现一个SQL解析器

文章插图
从上图中,我们可以看到,图左边在我们使用不带SQL的技术组件时 , 实现一个查询时,需要我们编写不同的业务逻辑接口,来与Kafka、HBase这些技术组件来进行数据交互 。如果随着这类组件的增加,查询功能复杂度的增加,那边每套接口的复杂度也会随之增加,对于后续的扩展和维护也是很不方便的 。而图右边在我们引入SQL解析器后,只需要一套接口来完成业务逻辑 , 对于不同的技术组件进行适配即可 。
三、什么是SQL解析器?在选择SQL解析器应用到我们实际的业务场景之前,我们先来了解一下SQL解析器的核心知识点 。
3.1 SQL解析器包含哪些内容?在使用SQL解析器时,解析SQL的步骤与我们解析Java/Python程序的步骤是非常的相似的 , 比如:
  • 在C/C++中,我们可以使用LEX和YACC来做词法分析和语法分析
  • 在Java中,我们可以使用JavaCC或ANTLR
在我们使用解析器的过程当中,通常解析器主要包括三部分,它们分别是:词法解析、语法解析、语义解析 。
3.1.1 什么词法解析?如何理解词法解析呢?词法解析我们可以这么来进行理解 , 在启动词法解析任务时,它将从左到右把字符一个个的读取并加载到解析程序里面 , 然后对字节流进行扫描 , 接着根据构词规则识别字符并切割成一个个的词条,切词的规则是遇到空格进行分割 , 遇到分号时结束词法解析 。比如一个简单的SQL如下所示:
SQL示例

如何实现一个SQL解析器

文章插图
SELECT name FROM tab;通过词法解析后,结果如下所示:
如何实现一个SQL解析器

文章插图
3.1.2 什么是语法解析?如何理解语法解析呢?语法解析我们可以这么来进行理解 , 在启动语法解析任务时,语法分析的任务会在词法分析的结果上将词条序列组合成不同语法短句,组成的语法短句将与相应的语法规则进行适配,若适配成功则生成对应的抽象语法树 , 否则报会抛出语法错误异常 。比如如下SQL语句:
SQL示例
如何实现一个SQL解析器

文章插图
SELECT name FROM tab WHERE id=1001;约定规则如下:
如何实现一个SQL解析器

文章插图
上表中,红色的内容通常表示终结符,它们一般是大写的关键字或者符号等 , 小写的内容是非终结符,一般用作规则的命名,比如字段、表名等 。具体AST数据结构如下图所示:
如何实现一个SQL解析器

文章插图
3.1.3 什么是语义解析?如何理解语义解析呢?语义解析我们可以这么来进行理解 , 语义分析的任务是对语法解析得到的抽象语法树进行有效的校验,比如字段、字段类型、函数、表等进行检查 。比如如下语句:

推荐阅读