MaxCompute推出了Object Table功能,該功能支援數倉計算引擎訪問資料湖儲存中的非結構化資料及其元資訊。本文為您介紹Object Table相關的命令文法和樣本。
背景資訊
許多AI流程環節需要熟悉資料和業務的數倉開發人員,利用巨量資料平台提供的低成本大規模算力對大模型進行資料預先處理或非結構化資料處理。這些計算過程及其結果將與數倉或資料湖中的資料進行互動。
使用SQL處理非結構化資料存在以下問題。
巨量資料SQL引擎在讀取Object Storage Service檔案時並不感知對象的大小,因此缺乏依據來最佳化執行計畫。這使得控制並發或自動啟動合適的並發變得困難。同時,由於無法有效下推過濾條件,在資料扭曲的情況下,無法充分發揮算力的優勢。
Object Storage Service的元資訊讀取效能不足,每次查詢均需遠端存取儲存服務,導致延時較高。
只能在UDTF中以單進程串列方式擷取Object Storage Service的檔案清單,導致資料讀取效能較差。
需要在使用者自訂函數(UDF)中自主實現許可權打通的邏輯,並且需要實現UDF與儲存服務等之間的網路連接邏輯。
UDF在非結構化資料處理方面的能力不足,傳統資料倉儲缺乏靈活且安全的自訂鏡像上傳功能,同時也缺乏UDF的安全運行環境。此外,遠程調用需要與分散式運算服務進行並發對接。
功能說明
MaxCompute推出了Object Table功能,該功能支援數倉計算引擎訪問資料湖儲存中的非結構化資料及其元資訊,具備以下能力:
支援引擎以表的形式讀取OSS檔案元資訊。
基於Metadata Table能力,以版本化方式緩衝OSS檔案的各種元資訊,後續SQL引擎能基於Metadata Table實現有效查詢最佳化,包括資料過濾和條件下推等功能。
基於內建文檔函數以多種方式讀取非結構化資料檔案內容。
MaxCompute SQL引擎基於Object Table元資訊進行並發切分,啟動大規模分散式運算能力,以提高資料讀取和處理的效率。
支援使用者上傳自訂鏡像構建UDF,並處理引擎讀取的非結構化資料。
支援引擎處理非結構化資料,產生結構化資料結果並將其寫入資料倉儲的內部表和外部表格,後續支援產生非結構化資料結果,並通過Object Table寫回Object Storage Service服務。
支援Python生態系統的Maxframe引擎。
使用限制
MaxCompute專案需要支援Schema功能,詳情請參見Schema功能開啟。
MaxCompute需要支援2.0資料類型系統。
Object Table暫不支援分區。
費用說明
Object Table是OSS上檔案元資訊的集合,因此會對重新整理存入Object Table的中繼資料收取儲存費用,詳情請參見儲存費用。由於OSS上的檔案沒有儲存在MaxCompute內部,MaxCompute不收取儲存費用,具體儲存和訪問資料的費用由OSS儲存服務收取,詳情請參見OSS儲存費用。
在重新整理OSS元資訊的抽取任務中,掃描的每個檔案的
inputsize是一個與元資訊相關的值,而與檔案的實際大小無關。因此,重新整理計算任務的整體費用與OSS上對應檔案的實際大小無關,而是與檔案數量相關。詳情請參見SQL外部表格計費。使用Object Table及其相關中繼資料進行OSS非結構化資料的分析與提取,並進行相應處理,會產生計算費用。
在隨用隨付模式下,對Object Table的中繼資料分析按照內表進行計費,請參見SQL標準計費。而對OSS非結構化資料的內容進行處理則按照外表進行計費,請參見SQL外部表格計費。
在訂用帳戶付費模式下,均使用訂用帳戶的預付費資源,請參見計算費用(訂用帳戶)。
建立Object Table
文法
CREATE OBJECT TABLE [IF NOT EXISTS] <objecttable_name>
WITH SERDEPROPERTIES ('<key>' = '<value>')
LOCATION '<location>'
[TBLPROPERTIES ('<key>' = '<value>')]
[COMMENT '<comment>']
;Object Table需要在內部專案支援Schema模式下使用,同時開啟Schema文法開關。
Object Table不需要定義列,中繼資料資訊列由系統提供。
參數說明
參數 | 是否必填 | 說明 |
objecttable_name | 必填。 | 表名。 |
SERDEPROPERTIES ('<key>'='<value>') | 必填。 |
因 |
location | 必填。 |
|
TBLPROPERTIES ('<key>'='<value>') | 可選。 |
|
comment | 可選。 | 表注釋內容。 |
使用樣本
SET odps.namespace.schema=true;
CREATE OBJECT TABLE ot_demo_day
WITH serdeproperties (
'odps.properties.rolearn'='acs:ram::xxxxxx:role/aliyunodpsdefaultrole')
LOCATION 'oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/';查看Object Table屬性
文法
DESC <object_table_name>參數說明
object_table_name:必填,表名。
使用樣本
SET odps.namespace.schema=true;
DESC ot_demo_day; 返回結果如下。
+------------------------------------------------------------------------------------+
| Owner: ALIYUN$****@test.aliyunid.com |
| Project: test_objecttable |
| Schema: default |
| TableComment: |
+------------------------------------------------------------------------------------+
| CreateTime: 2024-09-02 20:01:56 |
| LastDDLTime: 2024-09-02 20:01:56 |
| LastModifiedTime: 2024-09-02 20:01:56 |
+------------------------------------------------------------------------------------+
| InternalTable: YES | Size: 0 |
+------------------------------------------------------------------------------------+
| Native Columns: |
+------------------------------------------------------------------------------------+
| Field | Type | Label | Comment |
+------------------------------------------------------------------------------------+
| key | varchar(2048) | | The name of the object. |
| size | bigint | | The size of the returned object in bytes. |
| type | varchar(32) | | The type of the object and valid values: Normal, Multipart, Appendable, and Symlink. |
| last_modified | timestamp | | The last modified time of the object. |
| storage_class | varchar(32) | | The storage class of the object. |
| etag | varchar(64) | | The entity tag (ETag). When an object is created, an ETag is created to identify the content of the object. |
| restore_info | varchar(256) | | The restoration status of the object. |
| owner_id | bigint | | The ID of the bucket owner. |
| owner_display_name | varchar(256) | | The display name of the bucket owner. |
+------------------------------------------------------------------------------------+返回結果部分列名說明。
列名 | 類型說明 | 是否支援NULL | 說明 |
key | VARCHAR(2048) 原生長度約束為1023。 | False | 對象在Object Table中的相對路徑名。 |
size | BIGINT | False | 對象的大小,單位為位元組。 |
type | VARCHAR(32) | False | 對象在OSS側的檔案類型:Normal、Multipart、Appendable和Symlink。 |
last_modified | TIMESTAMP_NTZ | False | 對象在OSS上的資料最後變更時間。 |
storage_class | VARCHAR(32) | False | 對象在OSS上的儲存類型。具體類型請參見儲存類型。 |
etag | VARCHAR(64) | False | ETag是在每個Object產生時建立的實體標記(一個簽名資訊),用於標識一個Object的內容在前後兩次更新過程中是否發生變化(但不是唯一性標記)。 |
restore_info | VARCHAR(256) | True | 描述一個對象是否被從冷存中恢複,如果是恢複過程中的對象,則有相關的資訊描述。 |
owner_id | BIGINT | True | 對象的所有者ID。 |
owner_display_name | VARCHAR(256) | True | 對象的所有者的名稱。 |
查看Object Table建表語句
文法
SHOW CREATE TABLE <object_table_name>;參數說明
object_table_name:必填,表名。
使用樣本
SET odps.namespace.schema=true;
SHOW CREATE TABLE ot_demo_day; 返回結果如下。
CREATE OBJECT TABLE IF NOT EXISTS yunqi_object_****.`default`.ot_demo_day
WITH SERDEPROPERTIES (
'serialization.format'='1',
'odps.properties.rolearn'='acs:ram::139699392458****:role/aliyunodpsdefaultrole')
LOCATION
'oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/'
TBLPROPERTIES (
'last_modified_time'='1731478307',
'transient_lastDdlTime'='1731478307',
'metadata.cache.mode'='manual',
'metadata.staleness.seconds'='3600');重新整理Object Table元資訊
Object Table的真實對象資料存放區於OSS中。在MaxCompute中,對這些對象資料的元資訊進行緩衝,並基於緩衝的中繼資料執行各種查詢和計算。因此,在實際使用Object Table之前,需要對其進行一些緩衝更新操作。可以通過手動重新整理或在建表時配置周期性重新整理參數。
無論是手動重新整理還是周期性重新整理,都是全量重新整理。
手動重新整理
每次重新整理均為全量元資訊同步,您可自主控制重新整理的時機與頻率。
文法
ALTER TABLE <objecttable_name> REFRESH METADATA;參數說明
objecttable_name:必填,表名。
使用樣本
SET odps.namespace.schema=true; ALTER TABLE ot_demo_day REFRESH METADATA;
周期性重新整理
如果Object Table映射的OSS目錄中的檔案經常發生變化,可以按周期重新整理中繼資料。只需要在建表時指定相關參數即可,減少維護的成本。
文法
SET odps.namespace.schema=true; SET odps.sql.type.system.odps2 = true; CREATE OBJECT TABLE ot_demo_day WITH serdeproperties ( 'odps.properties.rolearn'='acs:ram::xxxxxx:role/aliyunodpsdefaultrole' ) location 'oss://oss-cn-hangzhou-internal.aliyuncs.com/odps-external-****/ottest/' tblproperties ( 'metadata.cache.mode' = 'periodic', 'metadata.staleness.seconds' = '3600' );參數說明
metadata.staleness.seconds:重新整理周期。對於periodic模式來說,必須要指定這個參數,取值範圍為[1, 604800],表示1秒到1周範圍內。該參數並非強制性保障,調度器將儘可能按照該參數進行執行。metadata.cache.mode:重新整理觸發方式,有三種選擇。periodic:周期性觸發。crontab:定時重新整理。manual:手動觸發(預設),可以自主控制觸發時機。
定時重新整理
如果Object Table映射的OSS目錄中的檔案經常發生變化,可以設定定時重新整理中繼資料。只需要在建表時指定相關參數即可,減少維護的成本。
文法
SET odps.namespace.schema=true; SET odps.sql.type.system.odps2 = true; CREATE OBJECT TABLE ot_demo_day WITH SERDEPROPERTIES ( 'odps.properties.rolearn'='acs:ram::xxxxxx:role/aliyunodpsdefaultrole' ) LOCATION 'oss://oss-cn-region-internal.aliyuncs.com/odps-external-****/ottest/' TBLPROPERTIES ( 'metadata.cache.mode' = 'crontab', 'metadata.crontab.expression' = 'your_timed_expression' );參數說明
metadata.crontab.expression:定時任務運算式(即cron運算式格式)。如需設定每天下午2點觸發一次,則可以表示為0 0 14 * * ?,即0秒、0分、14時(即 14:00 = 下午2點)、*每天、*每月、?不指定星期(與“日”互斥,避免衝突)。metadata.cache.mode:重新整理觸發方式,有三種選擇。crontab:定時重新整理。periodic:周期性觸發。manual:手動觸發(預設),可以自主控制觸發時機。
查看重新整理任務
可以通過如下命令查看歷史的重新整理任務狀態。
SHOW refresh task history FOR object TABLE <object_table_name>;參數說明
<object_table_name>必須是一個Object Table;
傳回值:執行重新整理的執行個體ID(InstanceId)、開始時間(CreateTime)、結束時間(EndTime)、執行狀態(Status)。
當執行狀態(Status)值為Failed時,可通過
wait InstanceId;列印log view查看報錯明細。
使用樣本
-- 查看Object Table的歷史重新整理任務 SET odps.namespace.schema=true; SHOW refresh task history for object table ot_demo_day04; -- 返回結果。 ID = 20260105*******f +---------------------------------------------------------------------------------------------------+ | Project: test_project | | Schema: default | | Task: *** | +---------------------------------------------------------------------------------------------------+ | History: | +---------------------------------------------------------------------------------------------------+ | InstanceId | CreateTime | EndTime | Status | +---------------------------------------------------------------------------------------------------+ | 20260105******************ks | 2026-01-05 14:12:00 | 2026-01-05 14:12:04 | Terminated | | 20260105******************y3 | 2026-01-05 14:10:00 | 2026-01-05 14:10:03 | Terminated | +---------------------------------------------------------------------------------------------------+ OK
查詢Object Table
Object Table擷取了OSS目錄中檔案的元資訊,您可以通過查詢Object Table明細來瀏覽這些元資訊,也可以使用SQL語句對元資訊進行過濾、匹配等計算,包括但不限於Aggregation、Join、Window、Order By、Limit等。
文法
SELECT * FROM <object_table_name>;參數說明
object_table_name:必填,表名。
使用樣本
-- 查詢上傳至指定OSS對象目錄下的資料,若資料量大,可以選擇查看5條。
SET odps.namespace.schema=true;
SELECT * FROM ot_demo_day [limit 5];通過Pseudo Column查詢對象的位元據
Pseudo Column(偽列)建表時無需定義,系統自動產生。可以通過Pseudo Column直接查詢Object Table中對象的位元據,有如下三種方式:
_data列
_data列返回對象的完整位元據(如圖片的二進位流),資料類型為BINARY。
單個對象的位元據不宜過大,否則可能導致記憶體溢出。
_data的優勢是簡單,天然支援現有的很多函數。
使用方式如下:
SET odps.namespace.schema=true; SELECT _data FROM test_ot1;_blob列
_blob列返回用於下載位元據的引用連結(為了延遲讀取真實資料,從而控制SQL的運算元在流轉過程中的記憶體消耗),而非位元據本身,資料類型為Blob,具體可參考Blob資料類型與多模態儲存。
相比_data列,_blob列在計算穩定性和資源消耗方面更有優勢。
對於較小的對象(平均1MB以下),建議直接使用_data列;
對於較大的對象,建議使用_blob列。_blob的優勢是延遲消費,在SQL運算元流轉過程中不佔用太多記憶體,等到遇到真正能處理BLOB類型的運算元/函數時再流式消費,達到延遲消費和控制記憶體的效果。
使用方式如下:
SET odps.namespace.schema=true; SELECT _blob FROM test_ot1;_signed_url列
_signed_url列可以免登上傳或下載位元據的URL,跨系統、跨程式、異構情境訪問的,建議用_signed_url。
使用方式如下:
SET odps.namespace.schema=true; SELECT _signed_url FROM test_ot1;
使用樣本
_data列
下載測試檔案並上傳至OSS:ot_test.txt。
建立Object Table
SET odps.namespace.schema=true; SET odps.sql.type.system.odps2=true; SET odps.mcqa.disable=TRUE; DROP TABLE IF EXISTS test_ot1; CREATE OBJECT TABLE test_ot1 LOCATION 'oss://oss-cn-<region>-internal.aliyuncs.com/<bucket name>/<file path>/'; -- 重新整理表緩衝 ALTER TABLE test_ot1 REFRESH METADATA; SET odps.mcqa.disable=TRUE; SET odps.namespace.schema=true; SELECT * FROM test_ot1; -- 返回結果如下: +------+------------+------+---------------+---------------+------+--------------+------------+--------------------+ | key | size | type | last_modified | storage_class | etag | restore_info | owner_id | owner_display_name | +------+------------+------+---------------+---------------+------+--------------+------------+--------------------+ | ot_test.txt | 286 |Normal|2026-07-21 06:49:59| Standard | 3*01 | NONE | 1***279014 | 1***279014 | +------+------------+------+---------------+---------------+------+--------------+------------+--------------------+讀取data列。
SET odps.namespace.schema=true; SELECT _data FROM test_ot1; -- 返回結果如下: +-------+ | _data | +-------+ | {=0A=20=20"id":=20**1,=0A=20=20"title":=20"Hello=20World",=0A=20=20"description":=20"=E8=BF**E4=BE=8B=20JSON=20=**82",=0A=20=20"tags":=20[=0A*=20"=E7**=8B",=0A=20=20=20=20"JSON",=0A=20=20=20=20"Example"=0A=20=20],=0A=20=20"metadata":=20{=0A=20=20=20=20"author":=20"AI=20Assistant",=0A=20=20=20=20"created_at":=20"2023-10-01T12:00:00Z",=0A=20=20=20=20"is_active":=20true=0A=20=20}=0A} |查看常值內容
SET odps.namespace.schema=true; SELECT CAST(_data AS STRING) FROM test_ot1; -- 返回結果如下: +-----+ | _c0 | +-----+ | { "id": 1001, "title": "Hello World", "description": "這是一個包含中英文的樣本 JSON 資料。", "tags": [ "編程", "JSON", "Example" ], "metadata": { "author": "AI Assistant", "created_at": "2023-10-01T12:00:00Z", "is_active": true } } | +-----+
_blob列
下載測試檔案並上傳至OSS:ot_test.txt。
建立Object Table
SET odps.namespace.schema=true; SET odps.sql.type.system.odps2=true; SET odps.mcqa.disable=TRUE; DROP TABLE IF EXISTS test_ot1; CREATE OBJECT TABLE test_ot1 LOCATION 'oss://oss-cn-<region>-internal.aliyuncs.com/<bucket name>/<file path>/'; -- 重新整理表緩衝 ALTER TABLE test_ot1 REFRESH METADATA; SET odps.mcqa.disable=TRUE; SET odps.namespace.schema=true; SELECT * FROM test_ot1; -- 返回結果如下: +------+------------+------+---------------+---------------+------+--------------+------------+--------------------+ | key | size | type | last_modified | storage_class | etag | restore_info | owner_id | owner_display_name | +------+------------+------+---------------+---------------+------+--------------+------------+--------------------+ | ot_test.txt | 286 |Normal|2026-07-21 06:49:59| Standard | 3*01 | NONE | 1***279014 | 1***279014 | +------+------------+------+---------------+---------------+------+--------------+------------+--------------------+讀取blob列。
SET odps.namespace.schema=true; SELECT _blob FROM test_ot1; -- 返回結果如下: +-------+ | _blob | +-------+ | CAEQAxruAgEAAAANA**AAEb2svMjAy3CIAKhR5WVBc/0S4GmxSm4psPJ5CV3k4STIeCgl***FyYTQ1ZXEx | +-------+查看常值內容
SET odps.namespace.schema=true; SELECT CAST(read_blob(_blob) AS STRING) FROM test_ot1; -- 返回結果如下: +-----+ | _c0 | +-----+ | { "id": 1001, "title": "Hello World", "description": "這是一個包含中英文的樣本 JSON 資料。", "tags": [ "編程", "JSON", "Example" ], "metadata": { "author": "AI Assistant", "created_at": "2023-10-01T12:00:00Z", "is_active": true } } | +-----+
刪除Object Table
Object Table本身會緩衝使用者的元資訊,這將佔用一定的儲存空間併產生儲存成本。因此,如果使用者在業務上不再需要這些快取資料,可以選擇刪除Object Table表。如後續業務需要重新使用這些資料,可以重建Object Table。
文法
DROP TABLE [IF EXISTS] <object_table_name>; 參數說明
object_table_name:必填,表名。
使用樣本
SET odps.namespace.schema=true;
DROP TABLE IF EXISTS ot_demo_day;常見問題
ODPS-0010000:System internal error
現象
報錯資訊如下:
ODPS-0010000:System internal error - ActionHandler job failed with failinfo storage service worker error occured: common/io/oss/oss_file_system_cppsdk.cpp(919): OSSRequestException: Status: -50, RequestId: , ErrorCode: ClientError:-50, Message: E_HTTP_ERROR_CONN_REFUSED問題原因
建立Object Table時用了OSS的公網串連地址。
解決方式
建立Object Table時
location參數中的oss_endpoint需要用內網地址,擷取方式見參數說明。若修改為內網地址後仍然報錯,可以通過工單聯絡MaxCompute支援人員團隊擷取支援。
周期性重新整理不成功
現象
當建立Object Table時設定了周期性重新整理的參數,到達重新整理周期後,仍未進行重新整理。
解決方式
請檢查建立Object Table配置的location參數值是否用的是OSS內網網路網域名稱資訊,更多建立Object Table詳情見參數說明。