SQL 解析原理和使用场景
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 解析原理和使用场景相关推荐
- 基于简单sql语句的sql解析原理及在大数据中的应用
基于简单sql语句的sql解析原理及在大数据中的应用 李万鸿 老百姓呼吁打土豪分田地.共同富裕,总有一天会实现. 全面了解你所不知道的外星人和宇宙真想:http://pan.baidu.com/s/1 ...
- SQL解析在美团的应用
数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...
- SQL解析在美团点评中的应用
数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...
- 如何实现一个SQL解析器
1. 背景 随着技术的不断的发展,在大数据领域出现了越来越多的技术框架.而为了降低大数据的学习成本和难度,越来越多的大数据技术和应用开始支持SQL进行数据查询.SQL作为一个学习成本很低的语言,支持S ...
- SQL注入原理深度解析
在网页数据中注入SQL语句 对于Web应用来说,注射式攻击由来已久,攻击方式也五花八门,常见的攻击方式有SQL注射.命令注射以及新近才出现的XPath注射等等.本文将以SQL注射为例,在源码级对其攻击 ...
- 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 ...
- MySQL的SQL解析器是干什么的?底层原理是什么?
MySQL的SQL解析器(SQL parser)是一个负责将SQL语句转换为可执行的指令的组件.其主要功能是将输入的SQL语句分解为语法单元,然后将这些语法单元转换为内部表示的数据结构,最终生成一个可 ...
- 18C 也不能避免 SQL 解析的 Bug
作者简介 苏星开 云和恩墨南区交付技术顾问,曾服务过通信.能源生产.金融等行业客户,擅长 SQL 审核和优化,DataGuard 容灾等. 1 概述 在 Oracle 12.2 版本和新发布的18.0 ...
- SQL查询优化原理与向量化执行引擎
文章目录 1.SQL查询优化的目的 2.SQL 查询优化的基本原理之研究如何通过关系代数优化执行方案 3.总结使用关系代数进行查询优化的要点 4.SQL 查询优化的基础算法 5.Volcano Opt ...
最新文章
- 科技部发布新一批国家新一代人工智能开放创新平台
- tinymce4.x 上传本地图片(自己写个插件)
- 使用EntityFramework6连接MySql数据库(db first方式)
- Python--logging....实例应用
- java Date工具类
- 图解内存搜索工具初步使用
- 对SetViewportOrg和SetWindowOrg的理解
- 随机数排列JAVA_随机数生成器,按排序顺序
- C站最全Python库总结丨标准库+高级库
- python网址太长_python中url太长怎么解决
- 这个火热的社区都升级到2.0了,你还不知道它?
- python打包exe有什么用_Python 打包exe
- python读取txt文件报错:UnicodeDecodeError: 'utf8' codec can't decode byte 0xb3 in position 0的解决方法
- VIVADO 安装教程
- python极客项目编程百度云_Python极客项目编程pdf
- 金色传说:SAP-ABAP-销售订单增强:记录销售订单修改信息和修改原因
- C语言decompose函数,R语言时间序列应用(decompose、Holt-Winters初步)
- (附源码)mysql+ssm学生选课系统 毕业设计 170920
- 给夜神模拟器设置好了代理之后,无法上网了,在设置代理之前都能上网的
- 春招,秋招面试题总结