MaxCompute - ODPS重裝上陣 第三彈 - 複雜類型
摘要: MaxCompute(原ODPS)是阿里雲自主研發的具有業界領先水平的分散式大數據處理平台, 尤其在集團內部得到廣泛應用,支撐了多個BU的核心業務。 MaxCompute除了持續優化性能外,也致力於提升SQL語言的用戶體驗和表達能力,提高廣大ODPS開發者的生產力。
作者:振禹
原文:click.aliyun.com/m/40155/
MaxCompute(原ODPS)是阿里雲自主研發的具有業界領先水平的分散式大數據處理平台, 尤其在集團內部得到廣泛應用,支撐了多個BU的核心業務。 MaxCompute除了持續優化性能外,也致力於提升SQL語言的用戶體驗和表達能力,提高廣大ODPS開發者的生產力。
MaxCompute基於ODPS2.0新一代的SQL引擎,顯著提升了SQL語言編譯過程的易用性與語言的表達能力。我們在此推出MaxCompute(ODPS2.0)重裝上陣系列文章
第一彈 - 善用MaxCompute編譯器的錯誤和警告 第二彈 - 新的基本數據類型與內建函數 第三彈 - 複雜類型 第四彈 - CTE,VALUES,SEMIJOIN
上次向您介紹了 新的基本數據類型與內建函數,這次向您介紹複雜數據類型
原ODPS也支持兩種複雜類型,ARRAY, MAP,但是有些場景下還是不夠用
- 場景1 我的項目里,生成的一個中間表,為了優化性能,裡面有一列最好是個數組,因為如果把數組打散,每行上存一個元素,會因為其他列的重複導致數據量爆炸。首先想從上游表中生成這個數組,搜索半天文檔,發現唯一的方式是把源數據列先轉STRING,再用wm_concat聚合,再用split函數打散成ARRAY<STRING>,這樣原來類型信息丟了,不過STRING似乎也能用,好,繼續。後面的運算有個地方需要取數組最後一個元素,試圖用數組下標配合size函數,my_array[size(my_array)], 發現報告錯誤,下標必須是常量,可是我的數組不是定長的,看看有沒有函數能反轉數組呢?沒有!最後不得不放棄使用數組。。。
- 場景2 我的任務是為每個廣告生成一個曲線,代表隨著廣告商的出價由低到高,預計的impression, click次數的曲線。最自然的表達是有個數據結構,裡面存著出價,impression次數,click次數。可是ODPS不支持這樣的用法,只好encode成一個字元串,每次操作先編碼,再解碼。好麻煩,效率也很差,可是沒有辦法。。。
MaxCompute採用基於ODPS2.0的SQL引擎,大幅度改進了複雜類型並提供了配套的內建函數,基本解決了上述問題。
複雜類型的擴充
此文中採用MaxCompute Studio作展示 ( MaxCompute從2.8.0.2版本開始支持複雜類型,如果您的版本不夠新,請升級到最新版本 )。
首先,安裝MaxCompute Studio,導入測試MaxCompute項目,創建工程,建立一個新的MaxCompute腳本文件, 如下
運行後,可以在MaxCompute Studio的Project Explorer中找到新創建的表,察看錶的詳細信息,並預覽數據,如下圖
可以看到MaxCompute支持ARRAY, MAP, STRUCT類型,並且可以任意嵌套使用。
MaxCompute Studio支持含新類型表數據的導入導出,可參考此ATA文章
- MaxCompute支持的複雜類型見下表
複雜類型構造與操作函數
在UDF中使用複雜類型
原ODPS不支持在UDF中訪問任何複雜類型。MaxCompute Java UDF支持所有複雜類型,Python UDF也會在不久的將來支持。
JAVA UDF中複雜類型的表示方法
ODPS的UDF分為三大類:UDF,UDAF,UDTF,其中:
- UDAF和UDTF通過@Resolve annotation來指定sinature,在MaxCompute 2.0上線後,用戶將可以在Resolve annotation中。如
@Resolve("array<string>,struct<a1:bigint,b1:string>,string->map<string,bigint>,struct<b1:bigint, b2:binary>")
- UDF通過evaluate方法的signature來映射UDF的輸入輸出類型,此時參考MaxCompute類型與java類型的映射關係。其中array對應
java.util.List
, map對應java.util.Map
,struct對應com.aliyun.odps.data.Struct
。需要注意的是,com.aliyun.odps.data.Struct
從反射是看不出field name和field type的,所以需要用@Resolve
annotation來輔助,即如果需要再UDF中使用struct,要求在UDF class上也標註上@Resolve
註解,這個註解只會影響參數或返回值中包含com.aliyun.odps.data.Struct
的重載。目前class上只能提供一個@Resolve
annotation,因此一個UDF中帶有struct 參數或返回值的重載只能有一個。這個是目前的一個限制,我們正在改進,後續將會取消這一限制。
實際用例
如以下代碼,定義了一個有三個overloads的UDF,其中第一個用了array作為參數,第二個用了map作為參數,第三個用了struct。由於第三個overloads用了struct作為參數或者返回值,因此要求必須要對UDF class打上@Resolve
annotation,來指定struct的具體類型。
@Resolve("struct<a:bigint>,string->string")npublic class UdfArray extends UDF {n public String evaluate(List<String> vals, Long len) {n return vals.get(len.intValue());n }nn public String evaluate(Map<String,String> map, String key) {n return map.get(key);n }nn public String evaluate(Struct struct, String key) {n return struct.getFieldValue("a") + key;n }n}n
用戶可以直接將複雜類型傳入UDF中:
create function my_index as UdfArray using myjar.jar;nselect id, my_index(array(red, yellow, green), colorOrdinal) as color_name from colors;n
小節
MaxCompute豐富了複雜類型的支持,可以更好的適應各種應用場景。MaxCompute仍將在兼容性,表達能力等多方面持續改進類型系統。從本系列的下一篇起,開始介紹MaxCompute在SQL語言其他方面的改進!
更多技術乾貨敬請關注云棲社區知乎機構號:阿里云云棲社區 - 知乎
推薦閱讀:
※流式處理對 請求/響應 正文數據體的影響
※Akka HTTP 文檔 (非官方漢化)- 導讀
※雲計算的1024種玩法之零基礎入門
※KaliRouter安裝與使用全指南