shardingsphere分库分表项目实践4-sql解析sql改写
为什么要sql解析重写?
如果我们的系统数据库实现了分表,那么我们的sql中表名需要根据参数动态确定,那么代码怎么写?
方案1: 自己手动拼接, 比如 update t_user_${suffix} , ${suffix} 作为一个变量传递进来,这么变量怎么设置,自己可以通过硬编码,高级一点的写法就是可以用拦截器(AOP)统一设置。
方案2: 更高级一点的方案就是sql重写,代码中的sql就和没分表一样,直接写,框架层面做拦截,进行sql解析重写。
shardingsphere SQL解析重写原理:
任何一门计算机语言在编译或者解释阶段,为了让机器能够识别, 都需要将代码做结构化处理,最常见的就是完全结构化生成AST(抽象语法树Abstract Syntax Tree) 。
shardingsphere AST 解析:
提取关键信息token化:
shardingsphere 分表sql重写只需要重写表名 ,所以 token化的时候,只token化了表名部分,并且记录了 tableName 在原始sql 的开始位置startIndex 和结束位置 stopIndex
sql重写:
根据上一步token化的结果,就知道了表名在sql语句的开始和结束位置了,那么直接进行表名替换,sql 字符串拼接就行了。
真实表名直接根据配置规则计算出来就行了,具体算法见:
shardingsphere分库分表项目实践3-分库分表算法原理-CSDN博客
思考:
编程语言改写标准流程是:
源语言--------》AST -------》替换AST的节点(要修改的部分) -------》 遍历AST再次生成源语言
这个标准流程好处是功能强大能对任意部分修改,甚至将一种计算机语言翻译成另外一种,缺点就是代价大(计算量大、耗时)。
shardingsphere 只是结构化AST后对表名部分(自己感兴趣的)进行了字符串替换,这么做相比AST再逆向生sql 成性能更好,因为shardingsphere 分表场景比较特殊, 只需要对表名修改。
注意事项:
分库分表解决了单表单独库数据量大的问题,但因为需要做sql解析和重写,由于sql语句的复杂性,第三方分表分库组件都没办法对复杂sql 100% 支持,所以如果用了分表分库和第三方分表分库组件,那么sql语句就需要标准简单,否则会有sql无法解析兼容问题。
shardingsphere不支持的sql官方清单 :
SQL :: ShardingSphere