全部產品
Search
文件中心

MaxCompute:分區和列操作

更新時間:Jun 19, 2024

分區和列操作為您提供了變更MaxCompute中表的分區或列的操作方法,您可以根據實際業務情境執行相應操作。本文為您介紹如何添加或刪除分區、添加或修改列及注釋常用操作。

分區和列操作詳情請參見分區和列操作。分區和列操作常用命令如下。

類型功能角色操作入口
添加分區為已存在的分區表新增分區。具備修改表許可權(Alter)的使用者本文中的命令您可以在如下工具平台執行:
刪除分區為已存在的分區表刪除分區。
添加列名或注釋為已存在的非分區表或分區表添加列或注釋。
修改列名或注釋修改非分區表或分區表的列名或注釋。

添加分區

為已存在的分區表新增分區。

  • 限制條件

    • MaxCompute單表支援的分區數量上限為6萬個。

    • 對於有多級分區的表,如果需要添加新的分區值,必須指明全部的分區。

    • 僅支援新增分區值,不支援新增分區欄位。

  • 命令格式

    alter table <table_name> add [if not exists] partition <pt_spec> [partition <pt_spec> partition <pt_spec>...];
  • 參數說明

    • table_name:必填。待新增分區的分區表名稱。

    • if not exists:可選。如果未指定if not exists而同名的分區已存在,會執行失敗並返回報錯。

    • pt_spec:必填。新增的分區,格式為(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)partition_col是分區欄位,partition_col_value是分區值。分區欄位不區分大小寫,分區值區分大小寫。

  • 使用樣本

    • 樣本1:給表sale_detail添加一個分區,用來儲存2013年12月杭州地區的銷售記錄。

      alter table sale_detail add if not exists partition (sale_date='201312', region='hangzhou');
    • 樣本2:給表sale_detail同時添加兩個分區,用來儲存2013年12月北京和上海地區的銷售記錄。

      alter table sale_detail add if not exists partition (sale_date='201312', region='beijing') partition (sale_date='201312', region='shanghai');
    • 樣本3:給表sale_detail添加分區,僅指定一個分區欄位sale_date,返回報錯,需要同時指定2個分區欄位sale_date和region。

      alter table sale_detail add if not exists partition (sale_date='20111011');
    • 樣本4:增加Transaction Table2.0表分區

      --建立transation2.0表
      create table mf_tt (pk bigint not null primary key, 
                          val bigint not null) 
                   partitioned by (dd string, hh string) 
                   tblproperties ("transactional"="true"); 
                   
      --添加分區           
      alter table mf_tt add partition (dd='01', hh='01');
    • 樣本5:修改Transaction Table2.0表屬性

      --更新bucket資料,目前只支援分區表,不支援非分區表
      alter table mf_tt3 set tblproperties("write.bucket.num"="64");
      
      --更新retain屬性
      alter table mf_tt3 set tblproperties("acid.data.retain.hours"="60");

刪除分區

為已存在的分區表刪除分區。

MaxCompute支援通過條件式篩選方式刪除分區。如果您希望一次性刪除符合某個規則條件的多個分區,可以使用運算式指定篩選條件,通過篩選條件匹配分區並大量刪除分區。

  • 限制條件

    • 每個分區過濾子句只能訪問一個分區列。

    • 運算式用到的函數必須是內建的Scalar函數。

  • 注意事項

    • 刪除分區之後,MaxCompute專案的儲存量會降低。

    • 您可以結合MaxCompute提供的生命週期功能,實現自動回收舊分區的能力。更多生命週期資訊,請參見生命週期

  • 命令格式

    • 未指定篩選條件

      --一次刪除一個分區。
      alter table <table_name> drop [if exists] partition <pt_spec>;
      --一次刪除多個分區。
      alter table <table_name> drop [if exists] partition <pt_spec>,partition <pt_spec>[,partition <pt_spec>....];
    • 指定篩選條件

      alter table <table_name> drop [if exists] partition <partition_filtercondition>;
  • 參數說明

    • table_name:必填。待刪除分區的分區表名稱。

    • if exists:可選。如果未指定if exists且分區不存在,則返回報錯。

    • pt_spec:必填。刪除的分區。格式為(partition_col1 = partition_col_value1, partition_col2 = partition_col_value2, ...)partition_col是分區欄位,partition_col_value是分區值。分區欄位不區分大小寫,分區值區分大小寫。

    • partition_filtercondition:指定篩選條件時必填。分區篩選條件,不區分大小寫。格式為:

      partition_filtercondition
          : partition (<partition_col> <relational_operators> <partition_col_value>)
          | partition (scalar(<partition_col>) <relational_operators> <partition_col_value>)
          | partition (<partition_filtercondition1> AND|OR <partition_filtercondition2>)
          | partition (NOT <partition_filtercondition>)
          | partition (<partition_filtercondition1>)[,partition (<partition_filtercondition2>), ...]
      • partition_col:分區名稱。

      • relational_operators:關係運算子,詳情請參見運算子

      • partition_col_value:分區列比較值或Regex,與分區列資料類型保持一致。

      • scalar():Scalar函數。Scalar函數基於輸入值產生對應的標量,對分區列的值(partition_col)進行處理後再按照指定的關係運算子relational_operatorspartition_col_value做比較。

      • 分區過濾條件支援邏輯運算子NOT、AND和OR。支援通過NOT過濾條件子句,取過濾規則的補集。支援多個過濾條件子句以AND或OR的關係組成整體分區匹配規則。

      • 支援多個分區過濾子句,當多個分區過濾子句以英文逗號(,)分隔時,每個過濾子句的邏輯以OR的關係組成整體分區匹配規則。

  • 使用樣本

    • 未指定篩選條件

      --從表sale_detail中刪除一個分區,2013年12月杭州分區的銷售記錄。
      alter table sale_detail drop if exists partition(sale_date='201312',region='hangzhou'); 
      --從表sale_detail中同時刪除兩個分區,2013年12月杭州和上海分區的銷售記錄。
      alter table sale_detail drop if exists partition(sale_date='201312',region='hangzhou'),partition(sale_date='201312',region='shanghai');
    • 指定篩選條件

      --建立分區表。
      create table if not exists sale_detail(
      shop_name     STRING,
      customer_id   STRING,
      total_price   DOUBLE)
      partitioned by (sale_date STRING);
      --添加分區。
      alter table sale_detail add if not exists
      partition (sale_date= '201910')
      partition (sale_date= '201911')
      partition (sale_date= '201912')
      partition (sale_date= '202001')
      partition (sale_date= '202002')
      partition (sale_date= '202003')
      partition (sale_date= '202004')
      partition (sale_date= '202005')
      partition (sale_date= '202006')
      partition (sale_date= '202007');
      --大量刪除分區。
      alter table sale_detail drop if exists partition(sale_date < '201911');
      alter table sale_detail drop if exists partition(sale_date >= '202007');
      alter table sale_detail drop if exists partition(sale_date LIKE '20191%');
      alter table sale_detail drop if exists partition(sale_date IN ('202002','202004','202006'));
      alter table sale_detail drop if exists partition(sale_date BETWEEN '202001' AND '202007');
      alter table sale_detail drop if exists partition(substr(sale_date, 1, 4) = '2020');
      alter table sale_detail drop if exists partition(sale_date < '201912' OR sale_date >= '202006');
      alter table sale_detail drop if exists partition(sale_date > '201912' AND sale_date <= '202004');
      alter table sale_detail drop if exists partition(NOT sale_date > '202004');
      --支援多個分區過濾運算式,運算式之間是OR的關係。
      alter table sale_detail drop if exists partition(sale_date < '201911'), partition(sale_date >= '202007');
      --添加其他格式分區。
      alter table sale_detail add IF NOT EXISTS
      partition (sale_date= '2019-10-05') 
      partition (sale_date= '2019-10-06') 
      partition (sale_date= '2019-10-07');
      --大量刪除分區,使用Regex匹配分區。
      alter table sale_detail drop if exists partition(sale_date RLIKE '2019-\\d+-\\d+');
      --建立多級分區表。
      create table if not exists region_sale_detail(
      shop_name     STRING,
      customer_id   STRING,
      total_price   DOUBLE)
      partitioned by (sale_date STRING , region STRING );
      --添加分區。
      alter table region_sale_detail add IF NOT EXISTS
      partition (sale_date= '201910',region = 'shanghai')
      partition (sale_date= '201911',region = 'shanghai')
      partition (sale_date= '201912',region = 'shanghai')
      partition (sale_date= '202001',region = 'shanghai')
      partition (sale_date= '202002',region = 'shanghai')
      partition (sale_date= '201910',region = 'beijing')
      partition (sale_date= '201911',region = 'beijing')
      partition (sale_date= '201912',region = 'beijing')
      partition (sale_date= '202001',region = 'beijing')
      partition (sale_date= '202002',region = 'beijing');
      --執行如下語句大量刪除多級分區,兩個匹配條件是或的關係,會將sale_date小於201911或region等於beijing的分區都刪除掉。
      alter table region_sale_detail drop if exists partition(sale_date < '201911'),partition(region = 'beijing');
      --如果刪除sale_date小於201911且region等於beijing的分區,可以使用如下方法。
      alter table region_sale_detail drop if exists partition(sale_date < '201911', region = 'beijing');

      大量刪除多級分區時,在一個partition過濾子句中,不能根據多個分區列編寫組合條件匹配分區,如下語句會報錯FAILED: ODPS-0130071:[1,82] Semantic analysis exception - invalid column reference region, partition expression must have one and only one column reference

      --分區過濾子句只能訪問一個分區列,如下語句報錯。
      alter table region_sale_detail drop if exists partition(sale_date < '201911' AND region = 'beijing');

添加列或注釋

為已存在的非分區表或分區表添加列或注釋。

說明
  • MaxCompute已支援添加STRUCT類型的列,例如struct<x: string, y: bigint>map<string, struct<x: double, y: double>>。如果需要開通此功能,請設定以下參數,同時請注意使用限制,修改該參數需要等待10分鐘後才會生效:

    setproject odps.schema.evolution.enable=true;

    設定專案空間的Project級屬性,需操作帳號為專案的Owner或者帳號被賦予了專案層級的Super_Administrator或Admin角色,操作詳情請參見為使用者賦予內建管理角色

  • Transaction Table2.0不支援Schema Evolution功能,包括:刪除列、更改列順序、增加複雜資料類型列、更改列資料類型。

  • 命令格式

    alter table <table_name> add columns (<col_name1> <type1> comment ['<col_comment>'][, <col_name2> <type2> comment '<col_comment>'...]);
  • 參數說明

    • table_name:必填。待新增列的表名稱。添加的新列不支援指定順序,預設在最後一列。

    • col_name:必填。新增列的名稱。

    • type:必填。新增列的資料類型。

    • col_comment:可選。新增列的注釋。

  • 使用樣本

    • 樣本1:給表sale_detail添加兩個列。

      alter table sale_detail add columns (customer_name STRING, education BIGINT);
    • 樣本2:給表sale_detail添加兩個列並同時添加列注釋。

      alter table sale_detail add columns (customer_name STRING comment '客戶', education BIGINT comment '教育' );
    • 樣本3:給表sale_detail添加一個複雜資料類型列。

      alter table sale_detail add columns (region struct<province:string, area:string>);
    • 樣本4:增加Transaction Table2.0的列

      alter table mf_tt add columns (val2 bigint);

修改列名及注釋

修改非分區表或分區表的列名或注釋。

  • 命令格式

    alter table <table_name> change column <old_col_name> <new_col_name> <column_type> comment '<col_comment>';
  • 參數說明

    • table_name:必填。需要修改列名以及注釋的表名稱。

    • old_col_name:必填。需要修改的列名稱。old_col_name必須是已存在的列。

    • new_col_name:必填。新的列名稱。表中不能有名為new_col_name的列。

    • column_type:必填。列的資料類型。

    • col_comment:可選。修改後的注釋資訊。內容最長為1024位元組。

  • 使用樣本

    --修改表sale_detail的列名customer_name為customer_newname,注釋“客戶”為“customer”。
    alter table sale_detail change column customer_name customer_newname STRING comment 'customer';