如果你爱一个人,就让他写SQL,因为那是天堂。
如果你恨一个人,就让他写SQL,因为那是地狱。
天堂,是因为他如此简单,又功能强大,可以极大简化你的程序。
地狱,是因为他如此纷繁,复杂,还有各种方言标准,而且不通用,当你试图切换数据库产品的时候,什么叫生不如死 ......
那我们就不能构建一个统一的数据库语言么?这个真不能,不是技术上不能,而是利益趋势,大家坚守自己的方言堡垒,而且越建越高。
ORM或许是解决这个问题的一个途径,正如其名,既然是对象关系映射,未免就会是一套机械、呆板的程序,我们只能将关系和实体映射出来,所以,这并非是解决问题的根本途径,但不能否认它确实是最受欢迎,使用最广泛,代价最小的方案,没有之一。
那我们是不是能从SQL语言翻译的角度来解决这个问题呢?即在将SQL抛给数据库执行之前,进行一次翻译工作?
我们可以对SQL进行语法分析,形成一颗AST(抽象语法树),然后遍历解析
我们在遍历语法树的时候,就进行一次翻译转换,形成其他方言的SQL。
这个方案也许不尽善尽美,但是至少解决了一个类似“同声传译”的问题。
对上述模型进一步演化,在AST层面进行双向转化,那这个实现是不是就看起来非常优雅了?
我们已经定制了一条看似合理的Roadmap,那么如何将其实现落地呢?
下表,是我对可完成上述任务的框架进行的一些总结
个人是十分推崇Calcite的,因为其本身更像是一个没有物理引擎的数据库引擎,这可能听起来有点滑稽,但是确实,他可以很好的解析SQL,并生成执行计划,如果你想,也可以针对其进行你希望的优化,这就让我们的控制力大大加强了,至少在数据库之上,就可以“为所欲为”了。
Durid提供的方言包,比较多,上手比较容易(文末附录里,贴出了一个查询的AST,结构还是挺清晰的),不过如果想达到AST层面的转换,对整套API需要进行一定的手术才行。
Antlr 可以说是非常强大的,他是单纯的语法解析工具,但是其语法文件比起javacc来,何止是平易近人,简直就是平易近人... 而且,shardingsphere,presto都是基于其开发的。在代码仓库里,也有很多线程的语法文件,可以使用,不过要达到上述目的,也需要走很长的路。
本文转载自微信公众号「麒思妙想 」,可以通过以下二维码关注。转载本文请联系麒思妙想 公众号。