更新时间:2026-08-06 GMT+08:00
分享

扩展DDL语法

前提条件

需已存在Iceberg表,例如,执行以下命令创建表:

CREATE TABLE prod.db.sample (id bigint, data string, category string, ts timestamp, ts_day timestamp) USING iceberg PARTITIONED BY (category);

基本语法

在Spark中使用Iceberg SQL扩展时,可使用以下命令:

ALTER TABLE ... ADD PARTITION FIELD;

ALTER TABLE ADD/REPLACE/DROP PARTITION FIELD

  • ADD PARTITION FIELD

    Iceberg支持通过ADD PARTITION FIELD向分区规范中添加新的分区字段:

    ALTER TABLE prod.db.sample ADD PARTITION FIELD id;

    同时支持分区转换操作:

    • 示例一:
      ALTER TABLE prod.db.sample ADD PARTITION FIELD bucket(16, id);
    • 示例二:
      ALTER TABLE prod.db.sample ADD PARTITION FIELD truncate(4, data);
    • 示例三:
      ALTER TABLE prod.db.sample ADD PARTITION FIELD year(ts);

    添加分区字段属于元数据操作,不会更改任何现有表数据。新数据将按照新的分区方式写入,但现有数据仍保持原有的分区布局。在元数据表中,旧数据文件的新分区字段值将为null。

    当表的分区方式发生变化时,动态分区覆盖行为也会随之改变,因为动态覆盖会隐式替换分区。

  • DROP PARTITION FIELD

    可使用DROP PARTITION FIELD移除分区字段。即使分区被移除,对应的列仍会保留在表的Schema 中。

    删除分区字段属于元数据操作,不会更改任何现有表数据。新数据将按照新的分区方式写入,但现有数据仍保持原有的分区布局。

    • 移除分区字段:
      • 示例一:
        ALTER TABLE prod.db.sample DROP PARTITION FIELD category; 
      • 示例二:
        ALTER TABLE prod.db.sample DROP PARTITION FIELD bucket(16, id); 
      • 示例三:
        ALTER TABLE prod.db.sample DROP PARTITION FIELD truncate(4, data); 
      • 示例四:
        ALTER TABLE prod.db.sample DROP PARTITION FIELD year(ts); 
  • REPLACE PARTITION FIELD

    通过REPLACE PARTITION FIELD可在单次元数据更新中,用新的分区字段ts_day替换原有分区字段year(ts):

    • 示例一:
      ALTER TABLE prod.db.sample REPLACE PARTITION FIELD year(ts) WITH ts_day;
    • 示例二:
      ALTER TABLE prod.db.sample REPLACE PARTITION FIELD year(ts) WITH ts_day AS day_of_ts;

ALTER TABLE WRITE/LOCALLY ORDERED BY

  • WRITE ORDERED BY

    Iceberg表可配置排序规则,部分引擎会依据该规则,在向表写入数据时自动对数据进行排序。例如,Spark中的MERGE INTO操作会使用表的排序规则。

    可使用WRITE ORDERED BY子句为表设置写入排序规则,示例如下:

    • 示例一:
      ALTER TABLE prod.db.sample WRITE ORDERED BY category, id;
    • 示例二:
      ALTER TABLE prod.db.sample WRITE ORDERED BY category ASC, id DESC;
    • 示例三:
      ALTER TABLE prod.db.sample WRITE ORDERED BY category ASC NULLS LAST, id DESC NULLS FIRST;
    WRITE ORDERED BY用于设置全局排序规则,会对跨任务的行进行排序,类似于在INSERT命令中使用ORDER BY,例如:
    INSERT INTO prod.db.sample SELECT id, data, category, ts FROM {其他表} ORDER BY ts, category;

    若只需在每个任务内排序(而非跨任务排序),可使用LOCALLY ORDERED BY

    ALTER TABLE prod.db.sample WRITE LOCALLY ORDERED BY category, id;

    可使用UNORDERED取消表的排序顺序:

    ALTER TABLE prod.db.sample WRITE UNORDERED;
  • WRITE DISTRIBUTED BY PARTITION

    WRITE DISTRIBUTED BY PARTITION用于指定每个分区由单个写入器(writer)处理,其默认实现方式为哈希分布。

    ALTER TABLE prod.db.sample WRITE DISTRIBUTED BY PARTITION;

    DISTRIBUTED BY PARTITION可与LOCALLY ORDERED BY结合使用,实现按分区分布数据,同时在每个任务内对行进行本地排序:

    ALTER TABLE prod.db.sample WRITE DISTRIBUTED BY PARTITION LOCALLY ORDERED BY category, id;

ALTER TABLE SET/DROP IDENTIFIER FIELDS(MRS 3.6.0-LTS及之后版本)

执行以下命令在prod数据库的db模式中创建一个名为sample的Iceberg表,并按category列进行分区:

CREATE TABLE prod.db.sample (id bigint NOT NULL, data string NOT NULL, category string, ts timestamp, ts_day timestamp) USING iceberg PARTITIONED BY (category);
  • SET IDENTIFIER FIELDS

    Iceberg支持通过SET IDENTIFIER FIELDS为表规范设置标识字段。如果Spark表配置了标识字段,该表可支持Flink SQL的更新插入(upsert)操作。

    Iceberg不支持直接通过ALTER COLUMN id SET NOT NULL将现有可空字段改成非空字段。

    • 示例一,需确保字段无空值:
      ALTER TABLE prod.db.sample SET IDENTIFIER FIELDS id;
    • 示例二:
      ALTER TABLE prod.db.sample SET IDENTIFIER FIELDS id, data;

    标识字段在创建或添加时,必须是非空列(NOT NULL)。后续执行的ALTER TABLE ... SET IDENTIFIER FIELDS语句会覆盖之前的标识字段设置。

  • DROP IDENTIFIER FIELDS

    可使用DROP IDENTIFIER FIELDS移除标识字段,且即使标识字段被移除,对应的列仍会保留在表的Schema中。

    • 示例一,需确保字段无空值:
      ALTER TABLE prod.db.sample DROP IDENTIFIER FIELDS id;
    • 示例二:
      ALTER TABLE prod.db.sample DROP IDENTIFIER FIELDS id, data;

相关文档