淺析構建SQL-to-SQL的翻譯器
如果你愛一個人,就讓他寫SQL,因為那是天堂。
如果你恨一個人,就讓他寫SQL,因為那是地獄。
天堂,是因為他如此簡單,又功能強大,可以極大簡化你的程序。
地獄,是因為他如此紛繁,復雜,還有各種方言標準,而且不通用,當你試圖切換數據庫產品的時候,什么叫生不如死 ......
那我們就不能構建一個統一的數據庫語言么?這個真不能,不是技術上不能,而是利益趨勢,大家堅守自己的方言堡壘,而且越建越高。
ORM或許是解決這個問題的一個途徑,正如其名,既然是對象關系映射,未免就會是一套機械、呆板的程序,我們只能將關系和實體映射出來,所以,這并非是解決問題的根本途徑,但不能否認它確實是最受歡迎,使用最廣泛,代價最小的方案,沒有之一。
那我們是不是能從SQL語言翻譯的角度來解決這個問題呢?即在將SQL拋給數據庫執行之前,進行一次翻譯工作?
我們可以對SQL進行語法分析,形成一顆AST(抽象語法樹),然后遍歷解析
我們在遍歷語法樹的時候,就進行一次翻譯轉換,形成其他方言的SQL。
這個方案也許不盡善盡美,但是至少解決了一個類似“同聲傳譯”的問題。
對上述模型進一步演化,在AST層面進行雙向轉化,那這個實現是不是就看起來非常優雅了?
我們已經定制了一條看似合理的Roadmap,那么如何將其實現落地呢?
下表,是我對可完成上述任務的框架進行的一些總結
個人是十分推崇Calcite的,因為其本身更像是一個沒有物理引擎的數據庫引擎,這可能聽起來有點滑稽,但是確實,他可以很好的解析SQL,并生成執行計劃,如果你想,也可以針對其進行你希望的優化,這就讓我們的控制力大大加強了,至少在數據庫之上,就可以“為所欲為”了。
Durid提供的方言包,比較多,上手比較容易(文末附錄里,貼出了一個查詢的AST,結構還是挺清晰的),不過如果想達到AST層面的轉換,對整套API需要進行一定的手術才行。
Antlr 可以說是非常強大的,他是單純的語法解析工具,但是其語法文件比起javacc來,何止是平易近人,簡直就是平易近人... 而且,shardingsphere,presto都是基于其開發的。在代碼倉庫里,也有很多線程的語法文件,可以使用,不過要達到上述目的,也需要走很長的路。
本文轉載自微信公眾號「麒思妙想 」,可以通過以下二維碼關注。轉載本文請聯系麒思妙想 公眾號。