SQL解析是一项复杂的技术,一般都是由数据库厂商来掌握,由于这几年MySQL数据库中间件的兴起,需要支持读写分离、分库分表等功能,就必须从SQL中抽出表名、库名以及相关字段的值。因此像Java语言编写的Druid,Go语言编写的Kingshard等,都会对SQL进行部分解析

我们部门最近做的星云平台,内部有一个功能就是根据各种复杂的配置然后解析成可执行 SQL,这套解析框架是内部自己开发的,在配置相当复杂的时候生成的 SQL 也是非常的复杂,这个就可能出现 SQL 性能比较低下的问题,由于是异步全自动的取数过程,那么就考虑引入 SQL 解析优化引擎来内部动态优化生成的可执行 SQL

SQL解析与优化是属于编译器范畴,和C等其他语言的解析没有本质的区别。其中分为,词法分析、语法和语义分析、优化、执行代码生成。对应到MySQL的部分,如下图

词法分析

SQL解析由词法分析和语法/语义分析两个部分组成。词法分析主要是把输入转化成一个个Token。其中Token中包含Keyword(也称symbol)和非Keyword。例如,SQL语句 select username from userinfo,在分析之后,会得到4个Token,其中有2个Keyword,分别为select和from:

关键字 非关键字 关键字 非关键字
select username from userinfo

语法分析

语法分析就是生成语法树的过程。这是整个解析过程中最精华,最复杂的部分,不过这部分MySQL使用了Bison来完成。即使如此,如何设计合适的数据结构以及相关算法,去存储和遍历所有的信息,也是值得在这里研究的。

sql 语句:

select username from user where age > 20 and level > 5;

语法分析树:

上面的语法分析是 mysql 内部的 lexer 通过 c 语言完成的,其实也有很多语法编译框架用 java 写的语法解析框架,Druid 就是其中一个

Druid SQL Parser分三个模块:

- Parser

- AST

- Visitor

Parser

parser是将输入文本转换为ast(抽象语法树),parser有包括两个部分,Parser和Lexer,其中Lexer实现词法分析,Parser实现语法分析。

AST

AST是Abstract Syntax Tree的缩写,也就是抽象语法树。AST是parser输出的结果。这也是语法树的精髓了,sql解析,本质上就是把sql转为 ast语法树,拿到这个语法树后,我们就能做很多事了,遍历也好,加点,修改也好,都可以在ast上完成。

那么 ast 到底是什么东西?怎么去理解这个抽象语法树呢?

案例:4/(1+1)*2  这样一个数学公式

通过多个condition,以及左右叶子节点,就能构建足够复杂的语法树。那么为什么需要这么构建呢,当我们语法很简单时,那么无所谓,直接匹配字符串,或者正则也行,但是当语法足够复杂时,简单的匹配字符串,正则就不够用了,你很难检测语法是否正确,而且想要在此基础上增加语法,也几乎很难做到。而ast则把这些字符串变成结构化的数据了,你可以精确地知道一段代码里面有哪些变量名,函数名,组合条件,参数等,你可以非常精准地处理,相对于字符串处理来说,遍历数据大大降低的处理难度。而ast也常常用在如IDE中错误提示、自动补全、编译器、语法翻译、重构、代码混淆压缩转换等。

visitor

Visitor是遍历AST的手段,是处理AST最方便的模式,Visitor是一个接口,有缺省什么都没做的实现VistorAdapter。

我们可以实现不同的Visitor来满足不同的需求,Druid内置提供了如下Visitor:

- OutputVisitor用来把AST输出为字符串

- WallVisitor 来分析SQL语意来防御SQL注入攻击

- ParameterizedOutputVisitor用来合并未参数化的SQL进行统计

- EvalVisitor 用来对SQL表达式求值

- ExportParameterVisitor用来提取SQL中的变量参数

- SchemaStatVisitor 用来统计SQL中使用的表、字段、过滤条件、排序表达式、分组表达式

SQL解析使用场景

整个 SQL 解析的精髓就是理解 AST 树,那么我们拿到解析后的 SQL 可以做哪些事情呢?业界目前常用的是慢 SQL 优化、SQL 特征分析

优化分析案例(where 条件如下):

  • a)1=1 and (m > 3 and n > 4)
  • b)1=2 and (m > 3 and n > 4)
  • c)1=1 or (m > 3 and n > 4)

特征分析案例:

select username from user where age > 20 and level > 5;-- sql 的特征
select username from user where age > ? and level > ?;

业界著名的慢查询分析工具pt-query-digest,通过正则表达式实现这个功能但是这类处理办法Bug较多。接下来就介绍如何使用SQL解析,完成SQL特征的生成。

原始SQL pt-query-digest生成的特征 SQL解析器生成的特征
select * from email_template2 where id = 1 select * from mail_template? where id = ? select * from email_template2 where id = ?
REPLACE INTO a VALUES(‘INSERT INTO foo VALUES (1),(2)’) replace into a values(\‘insert into foo values(?+) replace into a values (?)

SQL 解析原理和使用场景相关推荐

  1. 基于简单sql语句的sql解析原理及在大数据中的应用

    基于简单sql语句的sql解析原理及在大数据中的应用 李万鸿 老百姓呼吁打土豪分田地.共同富裕,总有一天会实现. 全面了解你所不知道的外星人和宇宙真想:http://pan.baidu.com/s/1 ...

  2. SQL解析在美团的应用

    数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...

  3. SQL解析在美团点评中的应用

    数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...

  4. 如何实现一个SQL解析器

    1. 背景 随着技术的不断的发展,在大数据领域出现了越来越多的技术框架.而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进行数据查询.SQL作为一个学习成本很低的语言,支持S ...

  5. SQL注入原理深度解析

    在网页数据中注入SQL语句 对于Web应用来说,注射式攻击由来已久,攻击方式也五花八门,常见的攻击方式有SQL注射.命令注射以及新近才出现的XPath注射等等.本文将以SQL注射为例,在源码级对其攻击 ...

  6. Java解析SQL生成语法树_Atitit.sql ast 表达式 语法树 语法 解析原理与实现 java php c#.net js python...

    Atitit.sql ast 表达式 语法树 语法 解析原理与实现java php c#.net js python 1.1.Sql语法树ast如下图锁死 2.SQL语句解析的思路和过程 2.1.le ...

  7. MySQL的SQL解析器是干什么的?底层原理是什么?

    MySQL的SQL解析器(SQL parser)是一个负责将SQL语句转换为可执行的指令的组件.其主要功能是将输入的SQL语句分解为语法单元,然后将这些语法单元转换为内部表示的数据结构,最终生成一个可 ...

  8. 18C 也不能避免 SQL 解析的 Bug

    作者简介 苏星开 云和恩墨南区交付技术顾问,曾服务过通信.能源生产.金融等行业客户,擅长 SQL 审核和优化,DataGuard 容灾等. 1 概述 在 Oracle 12.2 版本和新发布的18.0 ...

  9. SQL查询优化原理与向量化执行引擎

    文章目录 1.SQL查询优化的目的 2.SQL 查询优化的基本原理之研究如何通过关系代数优化执行方案 3.总结使用关系代数进行查询优化的要点 4.SQL 查询优化的基础算法 5.Volcano Opt ...

最新文章

  1. 科技部发布新一批国家新一代人工智能开放创新平台
  2. tinymce4.x 上传本地图片(自己写个插件)
  3. 使用EntityFramework6连接MySql数据库(db first方式)
  4. Python--logging....实例应用
  5. java Date工具类
  6. 图解内存搜索工具初步使用
  7. 对SetViewportOrg和SetWindowOrg的理解
  8. 随机数排列JAVA_随机数生成器,按排序顺序
  9. C站最全Python库总结丨标准库+高级库
  10. python网址太长_python中url太长怎么解决
  11. 这个火热的社区都升级到2.0了,你还不知道它?
  12. python打包exe有什么用_Python 打包exe
  13. python读取txt文件报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0xb3 in position 0的解决方法
  14. VIVADO 安装教程
  15. python极客项目编程百度云_Python极客项目编程pdf
  16. 金色传说:SAP-ABAP-销售订单增强:记录销售订单修改信息和修改原因
  17. C语言decompose函数,R语言时间序列应用(decompose、Holt-Winters初步)
  18. (附源码)mysql+ssm学生选课系统 毕业设计 170920
  19. 给夜神模拟器设置好了代理之后,无法上网了,在设置代理之前都能上网的
  20. 春招,秋招面试题总结

热门文章

  1. Keras深度学习(4)-回归问题之预测房价
  2. 利用autojs脚本开启QtScrcpy远程投屏
  3. 【python绘图(一)】Python数据分析和可视化
  4. 深圳华为鸿蒙发布会,鸿蒙手机要来了 华为下周举行鸿蒙操作系统发布会
  5. C++spdlog学习总结
  6. 路由器市场发展良好 2020年将达34亿美元
  7. 2021年全球合成石墨收入大约8775.9百万美元,预计2028年达到11120百万美元
  8. P99 是如何计算的?
  9. 马老师力荐:腾讯 SpringBoot 高阶笔记,限时开源
  10. (最详细)小米Note 3的Usb调试模式在哪里打开的流程