數據蔣堂 | 從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語法也不適合采用編譯型語言來實現。編譯器不能確定這個寫到參數位置的表達式是應該當場計算出表達式的值再傳遞,還是把整個表達式編譯成一個函數傳遞,需要再設計更多的語法符號加以區分。而解釋型語言則沒有這個問題,作為參數的表達式是先計算還是遍曆集合成員時再計算,可以由函數本身來決定。解釋執行是集合化語言的另一個重要特征。
清華大學計算機碩士,著有《非線性報表模型原理》等,1989年,中國首個國際奧林匹克數學競賽團體冠軍成員,個人金牌;2000年,創立潤乾公司;2004年,首次在潤乾報表中提出非線性報表模型,完美解決了中國式複雜報表製表難題,目前該模型已經成為報表行業的標準;2014年,經過7年開發,潤乾軟件發布不依賴關係代數模型的計算引擎——集算器,有效地提高了複雜結構化大數據計算的開發和運算效率;2015年,潤乾軟件被福布斯中文網站評為“2015福布斯中國非上市潛力企業100強”;2016年,榮獲中國電子信息產業發展研究院評選的“2016年中國軟件和信息服務業十大領軍人物”;2017年, 自主創新研發新一代的數據倉庫、雲數據庫等產品即將麵世。
《數據蔣堂》的作者蔣步星,從事信息係統建設和數據處理長達20多年的時間。他豐富的工程經驗與深厚的理論功底相互融合、創新思想與傳統觀念的相互碰撞,虛擬與現實的相互交織,產生出了一篇篇的瀝血之作。此連載的內容涉及從數據呈現、采集到加工計算再到存儲以及挖掘等各個方麵。大可觀數據世界之遠景、小可看技術疑難之細節。針對數據領域一些技術難點,站在研發人員的角度從淺入深,進行全方位、360度無死角深度剖析;對於一些業內觀點,站在技術人員角度闡述自己的思考和理解。蔣步星還會對大數據的發展,站在業內專家角度給予預測和推斷。靜下心來認真研讀你會發現,《數據蔣堂》的文章,有的會讓用戶避免重複前人走過的彎路,有的會讓攻城獅麵對紮心的難題茅塞頓開,有的會為初入行業的讀者提供一把開啟數據世界的鑰匙,有的甚至會讓業內專家大跌眼鏡,產生思想交鋒。
原文發布時間為:2017-08-19
本文作者:蔣步星
本文來自雲棲社區合作夥伴“數據派THU”,了解相關信息可以關注“數據派THU”微信公眾號
最後更新:2017-10-11 11:34:28