代码实现sql编译器_【数据蒋堂】第 19 期:从 SQL 语法看集合化
【數據蔣堂】第 19 期:從 SQL 語法看集合化
SQL 作為最常用的結構化數據計算語言,雖然在做一些細致處理時不太方便,但用于描述基本運算還是比 Java 等高級語言要簡單許多。這是因為 SQL 是一種集合化的語言,而 Java 等語言不是。我們下面從 SQL 的語法上看集合化語言的一些特征,為了方便討論,我們就用 Java 作為參照語言,其它高級語言是類似的。
集合運算能力
結構化數據經常是批量(以集合形式)出現的,為了方便地計算這類數據,程序設計語言有必要提供足夠的集合運算能力。
Java 等高級語言則沒有直接提供集合運算類庫,雖然也有數組(相當于集合)數據類型,但并沒有定義多少基本運算,以至于我們要對數據成員做個簡單地求和也需要寫四五行循環語句才能完成,而要做過濾、分組聚合等運算則常常要寫出數百行代碼。代碼過長不僅僅是寫起來很繁瑣,而且也不利于理解算法的整體結構,算法過程都湮沒在細節處理中。
而 SQL 則提供有較豐富的集合運算,如 SUM/COUNT 等聚合運算,WHERE 用于過濾、GROUP 用于分組,也支持針對集合的交、并、差等基本運算。這樣寫出來的代碼就會短小很多。
表達式參數
那么,有了集合運算能力是否就夠了呢?假如,我們為 Java 這類語言開發一批的集合運算類庫,是否就可以達到 SQL 的效果呢?
沒有這么簡單!
我們來看一下過濾運算。過濾通常需要一個條件,把滿足條件的集合成員保留,更技術的說法,是保留條件計算結果為真的成員。在 SQL 中這個條件是以一個表達式形式出現的,比如寫 WHERE x>0,就表示保留那些使得 x>0 計算結果為真的成員。這個表達式 x>0 并不是在執行這個語句之前先計算好的,而是在針對集合成員遍歷時才計算的。本質上,這個表達式就是一個函數,是一個以當前集合成員為參數的函數。對于 WHERE 運算而言,相當于把一個用表達式定義的函數用作了 WHERE 的參數。
Java 的語法不能直接支持這種寫法。Java 當然也允許把一個函數作為參數傳遞給另一個函數,但寫法要麻煩很多,需要事先定義一個函數,代碼看起來非常臃腫。而直接把表達式寫到函數的參數中,會被先計算出來,而不是針對每個集合成員分別計算。
相比之下,SQL 這種用表達式直接定義函數而作為參數傳遞的方法,顯然要簡捷和直觀得多了。
這種寫法有一個術語叫做 lambda 語法,或者叫函數式語言。
SQL 中大量使用了 lambda 語法。除了過濾這種運算可以說必須要用外,有些并非必須的情況,使用了這種語法形式也會更為簡單。比如聚合函數中可以填入表達式來計算運算后的聚合值,如 sum(x*x) 計算平方和,這里 x*x 也是在 sum 的執行過程中再計算的。在不支持 lamdba 語法時,我們也可以先用集合運算計算出成員平方構成的集合,再針對這個集合進行地求和,但寫法上就不如使用 lamdba 語法更為直觀,畢竟針對單個成員的表達式要比針對整個集合的計算更容易書寫和理解。
直接引用字段
結構化數據并非簡單的單值,而是帶有字段的記錄。
我們看到,在 SQL 的表達式參數中引用記錄字段時,大多數情況可以直接使用字段名稱而不必指明字段所屬的記錄,只有在多個同名字段時才需要冠以表名(或表的別名)以示區分。
再來看 Java,即使我們可以容忍事先定義函數來變相實現 lambda 語法,也只能把當前記錄作為參數傳入這個函數,然后再寫計算式時就總要帶上這個記錄。比如用單價和數量計算金額時,如果用于表示當前成員的參數名為 x,則需要寫成 “x. 單價 *x. 數量”。而在 SQL 中可以更為直觀地寫成 “單價 * 數量”。
SQL 中這些看起來理所當然的語法風格,其實背后并沒有那么簡單,這需要精心設計后才能被解釋程序正確解析和運算。某些支持 lambda 語法的腳本語言就沒有這個特性,雖然可以用表達式定義函數作為參數傳遞,但必須寫成“x. 單價 *x. 數量”這種啰嗦的形式。有了直接引用字段的語法機制后,才可以說是專門面向結構化數據計算的語言。
動態數據結構
SQL 還能很好地支持動態數據結構。
結構化數據計算中,返回值經常也是有結構的數據,而結果數據結構和運算相關,沒辦法在代碼編寫之前就先準備好。所以需要支持動態的數據結構能力。
SQL 中任何一個 SELECT 語句都會產生一個新的數據結構,在代碼中可以隨意添加刪除字段,而不必事先定義結構(類)。Java 這類語言則不行,在代碼編譯階段就要把用到的結構(類)都定義好,原則上不能在執行過程中動態產生新的結構。
解釋型語言
動態數據結構不能在編譯型語言中實現。前面說到的 lambda 語法也不適合采用編譯型語言來實現。編譯器不能確定這個寫到參數位置的表達式是應該當場計算出表達式的值再傳遞,還是把整個表達式編譯成一個函數傳遞,需要再設計更多的語法符號加以區分。而解釋型語言則沒有這個問題,作為參數的表達式是先計算還是遍歷集合成員時再計算,可以由函數本身來決定。解釋執行是集合化語言的另一個重要特征。
總結
以上是生活随笔為你收集整理的代码实现sql编译器_【数据蒋堂】第 19 期:从 SQL 语法看集合化的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 小米私密文件储存位置(我的小米云服务)
 - 下一篇: 我的世界五大神器指令