摘要: MaxCompute(原ODPS)是阿里雲自主研發的具備業界領先水平的分佈式大數據處理平臺, 尤爲在集團內部獲得普遍應用,支撐了多個BU的核心業務。 MaxCompute除了持續優化性能外,也致力於提高SQL語言的用戶體驗和表達能力,提升廣大ODPS開發者的生產力。html
點此查看原文java
MaxCompute(原ODPS)是阿里雲自主研發的具備業界領先水平的分佈式大數據處理平臺, 尤爲在集團內部獲得普遍應用,支撐了多個BU的核心業務。 MaxCompute除了持續優化性能外,也致力於提高SQL語言的用戶體驗和表達能力,提升廣大ODPS開發者的生產力。sql
MaxCompute基於ODPS2.0新一代的SQL引擎,顯著提高了SQL語言編譯過程的易用性與語言的表達能力。咱們在此推出MaxCompute(ODPS2.0)重裝上陣系列文章數據庫
第一彈 - 善用MaxCompute編譯器的錯誤和警告
第二彈 - 新的基本數據類型與內建函數
第三彈 - 複雜類型
第四彈 - CTE,VALUES,SEMIJOINapache
上次向您介紹了 [編譯器的易用性改進] https://yq.aliyun.com/articles/225028),此次向您介紹新的基本數據類型與內建函數編程
原ODPS只有六種基本數據類型, bigint, double, decimal, string, datetime, boolean。通常用起來也還夠用,可是在某些場景下就不夠了數組
遷移完成後發現數據和原有系統對不上,是否是VARCHAR的截斷,INT的溢出行爲致使數據不一樣呢?仍是什麼其餘緣由,面對着現存系統,沒辦法,只好一點點看代碼,跑數據,作分析。原本覺得挺輕鬆的項目,花了幾周時間才搞定。。。編程語言
MaxCompute採用基於ODPS2.0的SQL引擎,大幅度擴充了基本類型並提供了配套的內建函數,基本解決了上述問題。分佈式
此文中採用MaxCompute Studio做展現,首先,安裝MaxCompute Studio,導入測試MaxCompute項目,建立工程,創建一個新的MaxCompute腳本文件, 以下函數
運行後,創建另外一個文件插入數據,以下:
運行後,能夠在MaxCompute Studio的Project Explorer中找到新建立的表,察看錶的詳細信息,並預覽數據,以下圖
能夠看到
MaxCompute Studio支持含新類型表數據的導入導出,可參考此ATA文章
若是不使用MaxCompute Studio,能夠在腳本中指定,set odps.sql.type.system.odps2=true;
。Studio實際上在後臺也是使用這個開關來控制是否啓用新類型。odps.sql.type.system.odps2設定爲true的時候,除了可使用新類型,也控制其它方面的一些行爲改變。將在相關部分說明。
若是須要在MaxCompute 項目中缺省打開,能夠聯繫您的項目管理員,在項目模板中設定。
類型 | 是否新增 | 常量定義 | 描述 |
---|---|---|---|
TINYINT | 是 | 1Y, -127Y | 8位有符號整形, 範圍-128到127 |
SMALLINT | 是 | 32767S, -100S | 16位有符號整形, 範圍-32768到32767 |
INT | 是 | 1000, -15645787 ( 注1 ) | 32位有符號整形, 範圍-2^31到2^31 - 1 |
BIGINT | 否 | 100000000000L, -1L | 64位有符號整形, 範圍-2^63 + 1到2^63 - 1 |
FLOAT | 是 | 無 | 32位二進制浮點型 |
DOUBLE | 否 | 3.1415926 1E+7 | 64位二進制浮點型 |
DECIMAL | 否 | 3.5BD, 99999999999.9999999BD | 10進制精確數字類型,整形部分範圍-10^36+1到10^36-1, 小數部分精確到10^-18 |
VARCHAR | 是 | 無 ( 注2 ) | 變長字符類型,n爲長度,取值範圍1到65535 |
STRING | 否 | "abc", 'bcd', "alibaba" 'inc' ( 注3 ) | 字符串類型,目前長度限制爲8M |
BINARY | 是 | 無 | 二進制數據類型,目前長度限制爲8M |
DATETIME | 否 | DATETIME '2017-11-11 00:00:00' | 日期時間類型,範圍從0001年1月1日到9999年12月31日, 精確到毫秒 |
TIMESTAMP | 是 | TIMESTAMP '2017-11-11 00:00:00.123456789' | 與時區無關的時間戳類型,範圍從0001年1月1日到9999年12月31日 23.59:59.999999999, 精確到納秒 ( 注4 ) |
BOOLEAN | 否 | TRUE,FALSE | boolean類型, 取值TRUE或FALSE |
新的隱式轉換規則表以下表 ( 注5 )
| | boolean | tinyint | smallint | int | bigint | float | double | decimal | string | varchar | timestamp | binary |
|--------------|---------|---------|----------|-------|--------|-------|--------|---------|--------|---------|-----------|--------|
| boolean to | TRUE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE |
| tinyint to | FALSE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| smallint to | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| int to | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| bigint to | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| float to | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| double to | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| decimal to | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | FALSE | FALSE |
| string to | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| varchar to | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | TRUE | FALSE | FALSE |
| timestamp to | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE | TRUE | TRUE | FALSE |
| binary to | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | FALSE | TRUE |
此外,還新增了DECIMAL類型與DATETIME的常量定義方式, 100BD就是數值爲100的DECIMAL,datetime '2017-11-11 00:00:00'就是個datetime類型的常量。常量定義的方便之處在於能夠直接用到values子句和values表中,之後會單獨介紹。
任何編程語言,包括SQL,無論語言自己多強大,如過沒有豐富的函數後者類庫支持,在應用的時候仍是會很不方便,MaxCompute配合新數據類型,大大豐富了內建函數,以下:
這些函數大部分與Hive的內建函數兼容,用法能夠直接參考Hive的文檔。與Hive不一樣的是MaxCompute提供的這些函數都是用本地代碼實現的高效版本。
新增的TIMESTAMP數據類型支持納秒級別的精度,與之配合,新增了MaxCompute特有的millisecond
, nanosecond
函數,能夠取出TIMESTAMP
, DATETIME
的毫秒部分與TIMESTAMP
的納秒部分。
如本系列上一篇中提到的,MaxCompute支持新的強制轉換寫法,例如,要強制bigint變量爲轉換爲string,能夠直接寫string(a_bigint)
, 和寫成cast(a_bigint as string)
是等效的。具體用哪一種形式徹底取決於您的偏好。
須要注意的是全部用來支持新類型的函數,例如current_timestamp
,也須要設定set odps.sql.type.system.odps2=true;
,不然會報告編譯錯誤。
分區類型的支持也進行了擴充,目前分區類型支持TINYINT, SMALLINT, INT, BIGINT, VARCHAR與STRING ( 注6 )
另外原ODPS在動態分區的時候,若是分區列的類型與對應SELECT列表中的列的類型不嚴格一致,會報錯。MaxCompute支持隱式類型轉換
例如:
set odps.sql.type.system.odps2=true; create table parttable(a int, b double) partitioned by (p string); insert into parttable partition(p) (p, a) select key, value, current_timestmap() from src; select * from parttable;
返回
a | b | p |
---|---|---|
0 | NULL | 2017-01-23 22:30:47.130406621 |
0 | NULL | 2017-01-23 22:30:47.130406621 |
能夠看到分區列p的值爲從timestamp類型隱含轉換而來。
目前,MaxCompute2.0的JAVA UDF已經支持了新類型,Python UDF會盡快實現。JAVA UDF使用新類型的方法以下:
max compute type | java type |
---|---|
tinyint | java.lang.Byte |
smallint | java.lang.Short |
int | java.lang.Integer |
bigint | java.lang.Long |
float | java.lang.Float |
double | java.lang.Double |
decimal | java.math.BigDecimal |
boolean | java.lang.Boolean |
string | java.lang.String |
varchar | com.aliyun.odps.data.Varchar |
binary | com.aliyun.odps.data.Binary |
datetime | java.util.Date |
timestamp | java.sql.Timestamp |
array | java.util.List |
map | java.util.Map |
struct | com.aliyun.odps.data.Struct |
須要注意的是這裏,array類型對應的java類型是List,而不是數組
MaxCompute大大擴充了基本數據類型與內建函數,能夠更好的適應豐富的應用場景。不過,不少比較複雜的場景僅使用基本類型仍然很麻煩,請期待MaxCompute重裝上陣下一篇,複雜類型的支持
!
create table a_bigint_table(a int); -- 這裏的int實際看成bigint處理 select cast(id as int) from mytable; -- 這裏的int實際看成bigint處理
爲了與ODPS原有模式兼容,MaxCompute在沒有設定odps.sql.type.system.odps2爲true的狀況下,仍然保留此轉換,可是會報告一個警告提示int被看成bigint處理了,若是您的腳本有此種狀況,建議所有改寫爲bigint,避免混淆。
meta_dev>set odps.sql.type.system.odps2=true;select nanosecond(current_timestamp());
輸出爲相似
+------+ | _c0 | +------+ | 877000000 | +------+
Timestamp常量與外部數據導入能夠支持納秒精度。
create table parttest (a bigint) partitioned by (pt bigint); insert into parttest partition(pt) select 1, 2 from dual; insert into parttest partition(pt) select 1, 10 from dual; select * from parttest where pt >= 2;
返回的結果只有一行,由於10被按照字符串和2比,沒能返回。爲了與ODPS原有模式兼容,MaxCompute在沒有設定odps.sql.type.system.odps2爲true的狀況下,仍然如此處理;在設定odps.sql.type.system.odps2爲true的狀況下,BIGINT類型的分區嚴格按照BIGINT類型處理。