本文為您介紹ORC格式的OSS外部表格的建立、讀取及寫入方法。
前提條件
已具備訪問OSS的許可權。阿里雲帳號(主帳號)、RAM使用者或RAMRole身份可以訪問OSS外部表格,授權資訊請參見OSS的STS模式授權。
(可選)已準備好OSS儲存空間(Bucket)、OSS目錄及OSS資料檔案。具體操作請參見建立儲存空間、管理目錄和簡單上傳。
MaxCompute已支援在OSS側自動建立目錄,對於攜帶外部表格及UDF的SQL語句,您可以通過一條SQL語句執行讀寫外部表格及UDF的操作。原手動建立目錄方式仍然支援。
已建立MaxCompute專案。具體操作請參見建立MaxCompute專案。
由於MaxCompute只在部分地區部署,跨地區的資料連通性可能存在問題,因此建議Bucket與MaxCompute專案所在地區保持一致。
已具備在MaxCompute專案中建立表(CreateTable)的許可權。表操作的許可權資訊請參見MaxCompute許可權。
使用限制
OSS外部表格不支援cluster屬性。
單個檔案大小不能超過3 GB,如果檔案過大,建議拆分。
注意事項
當ORC檔案中的Schema與外表Schema不一致時:
列數不一致:如果ORC檔案中的列數小於外表DDL的列數,則讀取ORC資料時,系統會將缺少的列值補充為NULL。反之(大於時),會丟棄超出的列資料。
列類型不一致:MaxCompute支援使用STRING類型接收ORC檔案中的INT類型資料(不推薦),使用INT類型接收STRING類型資料時,會將字串轉換為NULL,數字正常接收。
資料類型支援
下表中
表示支援,
表示不支援。
JNI模式(讀表時不使用Native ORC Reader):
set odps.ext.oss.orc.native=false;,支援讀寫。Native模式(讀表時使用Native ORC Reader):
set odps.ext.oss.orc.native=true;,僅支援讀。
資料類型 | 是否支援JNI模式 | 是否支援Native模式 |
TINYINT |
|
|
SMALLINT |
|
|
INT |
|
|
BIGINT |
|
|
BINARY |
|
|
FLOAT |
|
|
DOUBLE |
|
|
DECIMAL(precision,scale) |
|
|
VARCHAR(n) |
|
|
CHAR(n) |
|
|
STRING |
|
|
DATE |
|
|
DATETIME |
|
|
TIMESTAMP |
|
|
TIMESTAMP_NTZ |
|
|
BOOLEAN |
|
|
ARRAY |
|
|
MAP |
|
|
STRUCT |
|
|
JSON |
|
|
壓縮格式支援
當您需要讀寫壓縮屬性的OSS檔案時,需要在建表語句中添加with serdeproperties屬性配置,詳情請參見with serdeproperties屬性參數。
支援讀寫的資料檔案格式:以SNAPPY、ZLIB方式壓縮的ORC。
建立外部表格
文法結構
各格式的外部表格文法結構詳情,請參見OSS外部表格。
精簡文法結構
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [COMMENT <table_comment>] [PARTITIONED BY (<col_name> <data_type>, ...)] STORED AS orc LOCATION '<oss_location>';完整文法結構
CREATE EXTERNAL TABLE [IF NOT EXISTS] <mc_oss_extable_name> ( <col_name> <data_type>, ... ) [COMMENT <table_comment>] [PARTITIONED BY (<col_name> <data_type>, ...)] ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' WITH serdeproperties( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS orc LOCATION '<oss_location>' tblproperties ( '<xxx>'='<yyy>' );
公用參數
公用參數說明請參見基礎文法參數說明。
專屬參數
with serdeproperties屬性參數
property_name | 使用情境 | 說明 | property_value | 預設值 |
mcfed.orc.schema.resolution | 當同一張OSS外部表格中資料的Schema不一樣時,請添加該屬性。 | 用於設定ORC檔案解析方式, | name | 預設按列號解析。 等價於: |
tblproperties屬性參數
property_name | 使用情境 | 說明 | property_value | 預設值 |
mcfed.orc.compress | 當需要將ORC資料以壓縮方式寫入OSS時,請添加該屬性。 | ORC壓縮屬性。指定ORC資料的壓縮方式。 |
| 無 |
io.compression.codecs | 當OSS資料檔案為Raw-Snappy格式時,請添加該屬性。 | 配置該參數值為True時,MaxCompute才可以正常讀取壓縮資料,否則MaxCompute無法成功讀取資料。 | com.aliyun.odps.io.compress.SnappyRawCodec | 無 |
寫入資料
MaxCompute寫入文法詳情,請參見寫入文法說明。
查詢分析
情境樣本
建立以SNAPPY壓縮的ORC格式外表,並進行資料讀取和寫入操作。
執行下述範例程式碼時,請將代碼中的
<uid>替換為您的阿里雲帳號ID。下述樣本中使用的角色為
aliyunodpsdefaultrole,如果您想使用其他角色,需要將aliyunodpsdefaultrole替換為目標角色名稱,並為目標角色授予訪問OSS的許可權。
準備SNAPPY格式資料檔案。
在樣本資料的
oss-mc-testBucket中建立orc_snappy/dt=20250526目錄層級,並將snappy檔案存放在分區目錄dt=20250526下。建立SNAPPY壓縮格式的ORC外表。
CREATE EXTERNAL TABLE orc_data_type_snappy ( vehicleId INT, recordId INT, patientId INT, calls INT, locationLatitute DOUBLE, locationLongtitue DOUBLE, recordTime STRING, direction STRING ) PARTITIONED BY (dt STRING ) ROW FORMAT SERDE 'org.apache.hadoop.hive.ql.io.orc.OrcSerde' WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole' ) STORED AS ORC LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/oss-mc-test/orc_snappy/' tblproperties ( 'mcfed.orc.compress'='SNAPPY');引入分區資料。當建立的OSS外部表格為分區表時,需要額外執行引入分區資料的操作,詳情請參見補全OSS外部表格分區資料文法。
-- 引入分區資料 MSCK REPAIR TABLE orc_data_type_snappy ADD PARTITIONS;讀取ORC外表資料。
SELECT * FROM orc_data_type_snappy WHERE dt=20250526 LIMIT 10;返回結果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | dt | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | 1 | 12 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | 20250526 | | 1 | 1 | 51 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:00 | S | 20250526 | | 1 | 2 | 13 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:01 | NE | 20250526 | | 1 | 3 | 48 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:02 | NE | 20250526 | | 1 | 4 | 30 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:03 | W | 20250526 | | 1 | 5 | 47 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:04 | S | 20250526 | | 1 | 6 | 9 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:05 | S | 20250526 | | 1 | 7 | 53 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:06 | N | 20250526 | | 1 | 8 | 63 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:07 | SW | 20250526 | | 1 | 9 | 4 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:08 | NE | 20250526 | | 1 | 10 | 31 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:09 | N | 20250526 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+寫入資料至ORC外表,並查詢。
INSERT INTO orc_data_type_snappy PARTITION (dt ='20250526') VALUES (1,16,76,1,46.81006,-92.08174,'9/14/2014 0:10','SW'); -- 查詢新寫入的資料 SELECT * FROM orc_data_type_snappy WHERE dt = '20250526' AND recordid=16;返回結果如下:
+------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | vehicleid | recordid | patientid | calls | locationlatitute | locationlongtitue | recordtime | direction | dt | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+ | 1 | 16 | 76 | 1 | 46.81006 | -92.08174 | 9/14/2014 0:10 | SW | 20250526 | +------------+------------+------------+------------+------------------+-------------------+----------------+------------+------------+