如何实现一个SQL解析器

本文介绍了实现一个SQL解析器的重要性及其在大数据场景中的应用,详细讲解了SQL解析器的三个核心组成部分——词法解析、语法解析和语义解析。对比了ANTLR和Calcite两种主流SQL解析器,通过示例展示了它们的工作原理和实现过程。文章指出,Calcite由于其模块化和可插拔的特点,更适合用于实际业务需求。
摘要由CSDN通过智能技术生成

🚀 优质资源分享 🚀

学习路线指引(点击解锁) 知识定位 人群定位
🧡 Python实战微信订餐小程序 🧡 进阶级 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。
💛Python量化交易实战💛 入门级 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统

​作者:vivo 互联网搜索团队- Deng Jie

一、背景

随着技术的不断的发展,在大数据领域出现了越来越多的技术框架。而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进行数据查询。SQL作为一个学习成本很低的语言,支持SQL进行数据查询可以降低用户使用大数据的门槛,让更多的用户能够使用大数据。

本篇文章主要介绍如何实现一个SQL解析器来应用的业务当中,同时结合具体的案例来介绍SQL解析器的实践过程。

二、为什么需要SQL解析器?

在设计项目系统架构时,我们通常会做一些技术调研。我们会去考虑为什么需要SQL解析器?怎么判断选择的 SQL 解析器可以满足当前的技术要求?

2.1 传统的SQL查询

传统的SQL查询,依赖完整的数据库协议。比如数据存储在MySQL、Oracle等关系型数据库中,有标准的SQL语法。我们可以通过不同的SQL语句来实现业务需求,如下图所示:

图片

但是,在处理海量数据的时候,关系型数据库是难以满足实际的业务需求的,我们需要借助大数据生态圈的技术组件来解决实际的业务需求。

2.2 实际应用场景

在使用大数据生态圈的技术组件时,有些技术组件是自带SQL的,比如Hive、Spark、Flink等;而有些技术组件本身是不带SQL的,比如Kafka、HBase。下面,我们可以通过对比不带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示例

?

| 1 | SELECT name FROM tab; |

通过词法解析后,结果如下所示:

3.1.2 什么是语法解析?

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

SQL示例[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2z3XntD9-1666586011846)(https://img2022.cnblogs.com/blog/1622697/202210/1622697-20221021121007841-797802603.gif “点击并拖拽以移动”)]

?

| 1 | SELECT name FROM tab WHERE id=1001; |

约定规则如下:

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

图片

3.1.3 什么是语义解析?

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

SQL示例

?

| 1 | SELECT name FROM tab WHERE id=1001; |

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JSijZ0oN-1666586011849)(https://img2022.cnblogs.com/blog/1622697/202210/1622697-20221021121007841-797802603.gif “点击并拖拽以移动”)]

上述SQL语句,语义分析任务会做如下检查:

  • SQL语句中表名是否存在;
  • 字段name是否存在于表tab中;
  • WHERE条件中的id字段类型是否可以与1001进行比较操作。

上述检查结束后,语义解析会生成对应的表达式供优化器去使用。

四、 如何选择SQL解析器?

在了解了解析器的核心知识点后,如何选择合适的SQL解析器来应用到我们的实际业务当中呢?下面,我们来对比一下主流的两种SQL解析器。它们分别是ANTLR和Calcite。

4.1 ANTLR

ANTLR是一款功能强大的语法分析器生成器,可以用来读取、处理、执行和转换结构化文本或者二进制文件。在大数据的一些SQL框架里面有有广泛的应用,比如Hive的词法文件是ANTLR3写的,Presto词法文件也是ANTLR4实现的,SparkSQLambda词法文件也是用Presto的词法文件改写的,另外还有HBase的SQL工具Phoenix也是用ANTLR工具进行SQL解析的。

使用ANTLR来实现一条SQL,执行或者实现的过程大致是这样的,实现词法文件(.g4),生成词法分析器和语法分析器,生成抽象语法树(也就是我常说的AST),然后再遍历抽象语法树,生成语义树,访问统计信息,优化器生成逻辑执行计划,再生成物理执行计划去执行。

图片

官网示例:

ANTLR表达式

?

| 1 | assign : ID '=' expr ';' ; |

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FCTIjENw-1666586011851)(https://img2022.cnblogs.com/blog/1622697/202210/1622697-20221021121007841-797802603.gif “点击并拖拽以移动”)]
解析器的代码类似于下面这样:

ANTLR解析器代码[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0v6Vj1Ku-1666586011852)(https://img2022.cnblogs.com/blog/1622697/202210/1622697-20221021121007841-797802603.gif “点击并拖拽以移动”)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值