全部產品
Search
文件中心

MaxCompute:CREATE TABLE

更新時間:Jul 24, 2024

建立非分區表、分區表、外部表格或聚簇表。

限制條件

  • 分區表的分區層級不能超過6級。例如某張表以日期為分區列,分區層級為年/月/周/日/時/分

  • 一張表允許的分區個數支援按照具體的專案配置,預設為6萬個。

更多表的限制條件,請參見SQL使用限制項

命令格式

--建立新表。
 create [external] table [if not exists] <table_name>
 [(<col_name> <data_type> [not null] [default <default_value>] [comment <col_comment>], ...)]
 [comment <table_comment>]
 [partitioned by (<col_name> <data_type> [comment <col_comment>], ...)]
 --用於建立聚簇表時設定表的Shuffle和Sort屬性。
 [clustered by | range clustered by (<col_name> [, <col_name>, ...]) [sorted by (<col_name> [asc | desc] [, <col_name> [asc | desc] ...])] into <number_of_buckets> buckets] 
 --僅限外部表格。
 [stored by StorageHandler] 
 --僅限外部表格。
 [with serdeproperties (options)] 
 --僅限外部表格。
 [location <osslocation>] 
 --指定表為Transactional表,後續可以對該表執行更新或刪除表資料操作,但是Transactional表有部分使用限制,請根據需求建立。
 [tblproperties("transactional"="true")]   
 [lifecycle <days>];

--基於已存在的表建立新表並複製資料,但不複製分區屬性。
create table [if not exists] <table_name> [lifecycle <days>] as <select_statement>;

--基於已存在的表建立具備相同結構的新表但不複製資料。
create table [if not exists] <table_name> like <existing_table_name> [lifecycle <days>];

參數說明

參數

是否必選

說明

external

可選。

表示建立的表為外部表格。

if not exists

可選。

如果不指定if not exists選項而存在同名表,會報錯。如果指定if not exists,只要存在同名表,即使原表結構與要建立的目標表結構不一致,均返回成功。已存在的同名表的中繼資料資訊不會被改動。

table_name

必填。

表名。表名大小寫不敏感,不能有特殊字元,只能包含a~z、A~Z、數字和底線(_)。建議以字母開頭,名稱的長度不超過128位元組,否則報錯。

col_name

可選。

表的列名。列名大小寫不敏感,不能有特殊字元,只能包含a~z、A~Z、數字和底線(_)。建議以字母開頭,名稱的長度不超過128位元組,否則報錯。

col_comment

可選。

列的注釋內容。注釋內容為長度不超過1024位元組的有效字串,否則報錯。

data_type

可選。

列的資料類型,包含BIGINT、DOUBLE、BOOLEAN、DATETIME、DECIMAL和STRING等多種資料類型,詳情請參見資料類型版本說明

not null

可選。

禁止該列的值為NULL。更多修改非空屬性資訊,請參見修改表的列非空屬性

default_value

可選。

指定列的預設值,當insert操作不指定該列時,該列寫入預設值。

table_comment

可選。

表注釋內容。注釋內容為長度不超過1024位元組的有效字串,否則報錯。

partitioned by (<col_name> <data_type> [comment <col_comment>], ...

可選。

指定分區表的分區欄位。

  • col_name:表的分區列名。列名大小寫不敏感,不能有特殊字元,只能包含a~z、A~Z、數字和底線(_)。建議以字母開頭,名稱的長度不超過128位元組,否則報錯。

  • data_type:分區列的資料類型。MaxCompute 1.0版本僅支援STRING類型。MaxCompute 2.0版本擴充了分區類型,包含TINYINT、SMALLINT、INT、BIGINT、VARCHAR和STRING類型。詳情請參見資料類型版本說明。當使用分區欄位對錶進行分區時,新增分區、更新分區內資料和讀取分區資料均不需要做全表掃描,提高處理效率。

  • col_comment:分區列的注釋內容。注釋內容為長度不超過1024位元組的有效字串,否則報錯。

說明

分區值不能包含雙位元組字元(如中文),必須以字母開頭,包含字母、數字和允許的字元,長度不超過128位元組。允許的字元包括空格、冒號(:)、底線(_)、貨幣符號($)、井號(#)、英文句點(.)、驚嘆號(!)和at(@),其他字元的行為未定義,例如逸出字元\t\n/

clustered by | range clustered by (<col_name> [, <col_name>, ...]) [sorted by (<col_name> [asc | desc] [, <col_name> [asc | desc] ...])] into <number_of_buckets> buckets

可選。

用於建立聚簇表時設定表的Shuffle和Sort屬性。

聚簇表分為Hash聚簇表和Range聚簇表兩種:

  • Hash聚簇表

    • clustered by:指定Hash Key。MaxCompute將對指定列進行Hash運算,按照Hash值分散到各個Bucket中。為避免資料扭曲和熱點,並取得較好的並存執行效果,clustered by列適宜選擇取值範圍大,重複索引值少的列。此外,為了達到join最佳化的目的,也應該考慮選取常用的Join或Aggregation Key,即類似於傳統資料庫中的主鍵。

    • sorted by:指定Bucket內欄位的排序方式。建議sorted byclustered by保持一致,以取得較好的效能。此外,當指定sorted by子句後,MaxCompute將自動產生索引,並且在查詢時利用索引來加快執行。

    • number_of_buckets:指定雜湊桶的數量。該值必須填寫,且由資料量大小決定。此外,MaxCompute預設支援最多1111個Reducer,所以此處最多隻支援1111個雜湊桶。您可以使用set odps.stage.reducer.num =<並發數>;來提升這個限制,但最大不得超過4000,否則會影響效能。

      選擇雜湊桶數目時,請您遵循以下兩個原則:

      • 雜湊桶大小適中:建議每個Bucket的大小為500 MB左右。例如,分區大小估計為500 GB,初略估算Bucket數目應該設為1000,這樣平均每個Bucket大小約為500 MB。對於特別大的表,500 MB的限制可以突破,每個Bucket在2 GB~3 GB左右比較合適。同時,可以結合set odps.stage.reducer.num =<並發數>;來突破1111個桶的限制。

      • 對於join最佳化情境,去除Shuffle和Sort步驟能顯著提升效能。因此要求兩個表的雜湊桶數目成倍數關係,例如256和512。建議雜湊桶的數量統一使用2n,例如512、1024、2048或4096,這樣系統可以自動進行雜湊桶的分裂和合并,也可以去除Shuffle和Sort的步驟,提升執行效率。

  • Range聚簇表

    • range clustered by:指定範圍聚簇列。MaxCompute將對指定列進行分桶運算,按照分桶編號分散到各個Bucket中。

    • sorted by:指定Bucket內欄位的排序方式,使用方法與Hash聚簇表相同。

    • number_of_buckets:指定雜湊桶的數量。Range聚簇表的Bucket桶數沒有Hash聚簇表的2n最佳實務,在資料量分布合理的情況下,任何桶數都可以。Range聚簇表的Bucket數不是必須的,可以省略,此時系統會根據資料量自動決定最佳的Bucket數目。

    • 當Join或Aggregation的對象是Range聚簇表,且Join Key或Group Key是Range Clustering Key或其首碼時,可以通過控制Flag消除資料的重分布,即Shuffle Remove,提升執行效率。您可以通過set odps.optimizer.enable.range.partial.repartitioning=true/false;進行設定,預設關閉。

      說明
      • 聚簇表的優點:

        • 最佳化Bucket Pruning。

        • 最佳化Aggregation。

        • 最佳化儲存。

      • 聚簇表的限制:

        • 不支援insert into,只能通過insert overwrite來添加資料。

        • 不支援Tunnel直接Upload到Range聚簇表,因為Tunnel上傳資料是無序的。

stored by StorageHandler

可選。

按照外部表格資料格式指定StorageHandler。

with serdeproperties (options)

可選。

外部表格的授權、壓縮、字元解析等相關參數。

osslocation

可選。

外部表格資料OSS儲存位置,詳情請參見建立OSS外部表格

tblproperties("transactional"="true")

可選。

設定表為Transactional表。後續可以對Transactional表執行updatedelete操作實現行級更新或刪除資料。更多資訊,請參見更新或刪除資料(UPDATE | DELETE)

Transactional表的使用限制如下:

  • MaxCompute只允許在建立表時設定Transactional屬性。已建立的表不允許通過alter table方式修改Transactional屬性,執行如下語句會報錯:

    alter table not_txn_tbl set tblproperties("transactional"="true");
    --報錯。
    FAILED: Catalog Service Failed, ErrorCode: 151, Error Message: Set transactional is not supported
  • 在建立表時,不支援將聚簇表、外部表格設定為Transactional表。

  • 不支援MaxCompute內部表、外部表格、聚簇表與Transactional表互轉。

  • 不支援其他系統的作業(例如Spark on MaxCompute、PAI、Graph)訪問Transactional表。

  • 不支援clone tablemerge partition操作。

  • 在對Transactional表的重要資料執行updatedeleteinsert overwrite操作前需要手動通過select+insert操作將資料備份至其他表中。

lifecycle

可選。

表的生命週期,僅支援正整數。單位:天。

  • 非分區表:自最後一次修改表資料開始計算,經過days天后資料無改動,則您無需幹預此表,MaxCompute會自動回收(類似drop table操作)。

  • 分區表:系統根據各分區的LastModifiedTime判斷是否需要回收分區。不同於非分區表,分區表的最後一個分區被回收後,該表不會被刪除。生命週期只能設定到表層級,不支援在分區層級設定生命週期。

說明
  • 通過create table [if not exists] <table_name> [lifecycle <days>] as <select_statement>;語句可以再建立一個表,並在建表的同時將資料複製到新表中。但通過該語句建立的表不會複製分區屬性,只會把源表的分區列作為目標表的一般列處理,也不會複製源表的生命週期屬性。您還可以通過lifecycle參數回收表。

  • 通過create table [if not exists] <table_name> like <existing_table_name> [lifecycle <days>];語句可以再建立一個表,使目標表和源表具有相同的表結構。但通過該語句建立的表不複製資料,也不會複製源表的生命週期屬性。您還可以通過lifecycle參數回收表。

使用樣本

  • 樣本1:建立非分區表test1。

    create table test1 (key STRING);
  • 樣本2:建立一張分區表sale_detail。

    create table if not exists sale_detail(
     shop_name     STRING,
     customer_id   STRING,
     total_price   DOUBLE)
    partitioned by (sale_date STRING, region STRING); 
  • 樣本3:建立一個新表sale_detail_ctas1,將sale_detail的資料複製到sale_detail_ctas1中,並設定生命週期。

    create table sale_detail_ctas1 lifecycle 10 as select * from sale_detail;

    您可以通過desc extended sale_detail_ctas1;命令查看到表的結構及生命週期等詳細資料。

    此處sale_detail是一張分區表,而通過create table ... as select_statement ...語句建立的表sale_detail_ctas1不會複製分區屬性,只會把源表的分區列作為目標表的一般列處理。即sale_detail_ctas1是一個含有5列的非分區表。

  • 樣本4:建立一個新表sale_detail_ctas2,在select子句中使用常量作為列的值。

    --指定列的名字。
    create table sale_detail_ctas2
    as
    select shop_name, customer_id, total_price, '2013' as sale_date, 'China' as region
    from sale_detail;
    --不指定列的名字。
    create table sale_detail_ctas3
    as
    select shop_name, customer_id, total_price, '2013', 'China' 
    from sale_detail;
    說明

    如果在select子句中使用常量作為列的值,建議您指定列的名字。建立的表sale_detail_ctas3的第四、五列類似於_c4_c5

  • 樣本5:建立一個新表sale_detail_like,與sale_detail具有相同的表結構,並設定生命週期。

    create table sale_detail_like like sale_detail lifecycle 10;

    您可以通過desc extended sale_detail_like;命令查看到表的結構及生命週期等詳細資料。

    sale_detail_like的表結構與sale_detail完全相同。除生命週期屬性外,列名、列注釋以及表注釋等均相同。但sale_detail中的資料不會被複製到sale_detail_like表中。

  • 樣本6:建立使用新資料類型的表test_newtype。

    set odps.sql.type.system.odps2=true;
    CREATE TABLE test_newtype (
        c1 TINYINT
        ,c2 SMALLINT
        ,c3 INT
        ,c4 BIGINT
        ,c5 FLOAT
        ,c6 DOUBLE
        ,c7 DECIMAL
        ,c8 BINARY
        ,c9 TIMESTAMP
        ,c10 ARRAY<MAP<BIGINT,BIGINT>>
        ,c11 MAP<STRING,ARRAY<BIGINT>>
        ,c12 STRUCT<s1:STRING,s2:BIGINT>
        ,c13 VARCHAR(20))
    LIFECYCLE 1
    ;
  • 樣本7:建立Hash聚簇非分區表t1。

    create table t1 (a STRING, b STRING, c BIGINT) clustered by (c) sorted by (c) into 1024 buckets; 
  • 樣本8:建立Hash聚簇分區表t2。

    create table t2 (a STRING, b STRING, c BIGINT) partitioned by (dt STRING) clustered by (c) sorted by (c) into 1024 buckets; 
  • 樣本9:建立Range聚簇非分區表t3。

    create table t3 (a STRING, b STRING, c BIGINT) range clustered by (c) sorted by (c) into 1024 buckets;
  • 樣本10:建立Range聚簇分區表t4。

    create table t4 (a STRING, b STRING, c BIGINT) partitioned by (dt STRING) range clustered by (c) sorted by (c); 
  • 樣本11:建立Transactional非分區表t5。

    create table t5(id bigint) tblproperties("transactional"="true");
  • 樣本12:建立Transactional分區表t6。

    create table if not exists t6(id bigint) partitioned by(ds string) tblproperties ("transactional"="true");

相關命令

  • ALTER TABLE:修改表操作。

  • TRUNCATE:將指定表中的資料清空。

  • DROP TABLE:刪除分區表或非分區表。

  • DESC TABLE/VIEW:查看MaxCompute內部表、視圖、物化視圖、外部表格、聚簇表或Transactional表的資訊。

  • SHOW:查看錶的SQL DDL語句、列出專案下所有的表和視圖或列出一張表中的所有分區。