本文介绍如何创建并查询Iceberg外部表。
Apache Iceberg是一种流批一体的湖存储格式,具备高吞吐的写入和低延迟的查询能力,与常见计算引擎(如Spark、Hive、Flink)深度兼容。MaxCompute支持借助Apache Iceberg构建存储在OSS上的数据湖存储服务,并实现数据湖分析。
适用范围
MaxCompute内置Iceberg SDK版本为 1.6.1。
读:支持Iceberg table format v2的数据读,不支持time-travel。
写:支持insert into/overwrite ,不支持 upsert。
创建Iceberg外部表
Iceberg外部表两种创建模式:普通外部表和Delegate模式外部表。
创建普通外部表
语法
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 ICEBERG
WITH SERDEPROPERTIES (
'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
)
LOCATION '<oss_location>'
TBLPROPERTIES ('<tbproperty_name>'='<tbproperty_value>',...);普通外表需指定Iceberg Data Schema,即表列名及数据类型信息,且该信息不会随Iceberg Data Schema evolution自动更新。
普通外表可以指定一个空目录。第一次写数据,按照指定Schema创建Iceberg Data Schema。
参数
公共参数
公共参数说明请参见基础语法参数说明。
独有参数
当OSS数据文件为Iceberg时,添加如下TBLPROPERTIES属性:
property_name
说明
property_value
iceberg_uuid_fields
指定写出数据类型为uuid,多列以
;为分隔符,无默认值。指定多列
col1;col2。指定struct嵌套字段为uuid类型:
col_struct.field1。指定list元素为uuid类型:
col_list.entry。指定map类型key为uuid类型:
col_map.key。指定map类型value为uuid类型:
col_map.val。
iceberg_time_fields
指定写出数据类型为time,多列以
;为分隔符,无默认值。指定多列
col1;col2。指定struct嵌套字段为time类型:
col_struct.field1。指定list元素为time类型:
col_list.entry。指定map类型key为time类型:
col_map.key。指定map类型value为time类型:
col_map.val。
iceberg_write_data_format
指定写出的数据格式,默认为Parquet格式。
可选orc/parquet/avro。
创建Delegate模式外部表
语法
Delegate模式是基于湖格式(例如:Iceberg)内的元信息,提取并动态生成表Schema和分区的一种外表模式。
CREATE EXTERNAL TABLE [if NOT EXISTS] <mc_oss_extable_name>
[COMMENT <table_comment>]
STORED AS ICEBERG
LOCATION '<oss_location>'
TBLPROPERTIES (
'iceberg_write_data_format'='[parquet|orc|avro]',
'odps.properties.rolearn'='acs:ram::<uid>:role/aliyunodpsdefaultrole'
);建表无需指定Iceberg Data Schema,会检测指定目录的Iceberg Data Schema并
动态自动补全,每次读取时以当前文件的Schema为准。
建表不可以指定空目录,否则读写时报错。
参数
公共参数
公共参数说明请参见基础语法参数说明。
独有参数
当OSS数据文件为Iceberg时,添加如下TBLPROPERTIES属性:
property_name
说明
iceberg_write_data_format
指定写出的数据格式。
写入数据
MaxCompute写入语法详情,请参见语法说明。
beta版本需要加参数
set odps.service.mode=off;例如:-- # 需关闭online mode。 SET odps.service.mode=off; INSERT INTO <table-name> VALUES (...); INSERT OVERWRITE TABLE <table-name> VALUES (...);
查询分析
分区操作
普通外部表分区操作
普通Iceberg外部表分区操作支持情况,如下表:
操作类型 | 是否支持 |
添加分区 | |
修改分区的更新时间 | |
修改分区值 | |
合并分区 | |
列出所有分区 | |
查看分区信息 | |
删除分区 | |
清空分区数据 |
如无法直接列出分区或读出分区表数据,需执行引入分区命令,具体操作参考分区数据语法。
Delegate模式分区操作
Delegate模式不同于普通Iceberg外表,建表时无需指定分区字段,读表时分区字段会出现在最后一列。示例如下:
假设在OSS上已经存入分区文件。
创建外部表时,不需要指定分区键,非分区表和分区表在创建形式上相同。
CREATE EXTERNAL TABLE ext_tbl_iceberg_pt STORED AS ICEBERG LOCATION 'oss://oss-cn-REGION-internal.aliyuncs.com/OSS_PATH/' TBLPROPERTIES ( 'odps.properties.rolearn'='acs:ram::UID:role/aliyunodpsdefaultrole' );查询:直接在MaxCompute查询分区表,在查询结果最后一列能看到分区。
写入:写入分区表时,不需要指定分区,直接在末尾指定分区值,就会生成该分区目录。
其他DDL
查询建表语句
SHOW CREATE TABLE <table-name>;查看表详情
Delegate模式表默认不展示schema信息,如需展示需设置参数,如下:
-- 如需展示delegate模式表的schema信息,加如下开关。
SET odps.console.forward.commands.to.sql=true;
DESC [EXTENDED] <table-name>;使用示例
假设当前OSS上没有Iceberg文件。
创建普通外部表
创建普通Iceberg外表,并写入测试数据。
SET odps.service.mode=off; SET odps.sql.type.system.odps2=true; SET odps.sql.decimal.odps2=true; SET odps.sql.hive.compatible=true; CREATE EXTERNAL TABLE ext_tbl_iceberg_ordinary ( id bigint COMMENT '用户唯一标识ID', name string COMMENT '用户姓名', age bigint COMMENT '用户年龄', gender string COMMENT '用户性别', height float COMMENT '用户身高', birthday date COMMENT '用户生日', phone_number string COMMENT '用户电话号码', email string COMMENT '用户电子邮箱', address string COMMENT '用户地址', salary decimal(18, 2) COMMENT '用户薪水', create_time timestamp COMMENT '用户信息创建时间', update_time timestamp COMMENT '用户信息更新时间', is_deleted boolean COMMENT '用户信息是否被删除的标志位' ) STORED AS ICEBERG LOCATION 'oss://oss-cn-REGION-internal.aliyuncs.com/OSS_PATH/' TBLPROPERTIES ( 'iceberg_uuid_fields'='id', 'iceberg_write_data_format'='parquet', 'odps.properties.rolearn'='acs:ram::UID:role/aliyunodpsdefaultrole' ); INSERT INTO ext_tbl_iceberg_ordinary VALUES (1, '张三', 18, '男', 178.56, '1990-01-01', '13800000000', 'zhangsan@example.com', '北京市海淀区', 5000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00', false), (2, '李四', 20, '女', 162.70, '1992-02-02', '13900000000', 'lisi@example.com', '上海市浦东新区', 6000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00',false), (3, '王五', 22, '男', 185.21, '1994-03-03', '14000000000', 'wangwu@example.com', '深圳市南山区', 7000.00, '2023-04-19 11:32:00', '2023-04-19 11:32:00', false) ;读取普通外部表数据
SELECT * FROM ext_tbl_iceberg_ordinary; -- 返回结果如下: +------------+------+------------+--------+------------+----------+--------------+-------+---------+--------+-------------+-------------+------------+ | id | name | age | gender | height | birthday | phone_number | email | address | salary | create_time | update_time | is_deleted | +------------+------+------------+--------+------------+----------+--------------+-------+---------+--------+-------------+-------------+------------+ | 1 | 张三 | 18 | 男 | 178.56 | 1990-01-01 | 13800000000 | zhangsan@example.com | 北京市海淀区 | 5000 | 2023-04-19 11:32:00 | 2023-04-19 11:32:00 | false | | 2 | 李四 | 20 | 女 | 162.7 | 1992-02-02 | 13900000000 | lisi@example.com | 上海市浦东新区 | 6000 | 2023-04-19 11:32:00 | 2023-04-19 11:32:00 | false | | 3 | 王五 | 22 | 男 | 185.21 | 1994-03-03 | 14000000000 | wangwu@example.com | 深圳市南山区 | 7000 | 2023-04-19 11:32:00 | 2023-04-19 11:32:00 | false | +------------+------+------------+--------+------------+----------+--------------+-------+---------+--------+-------------+-------------+------------+
创建Delegate模式外部表
Delegate模式建表不可以指定空目录,否则读写时报错。所以需要保证OSS路径下有可读取的Iceberg数据。
创建Delegate模式外部表
SET odps.service.mode=off; CREATE EXTERNAL TABLE ext_tbl_iceberg_delegate STORED AS ICEBERG LOCATION 'oss://oss-cn-REGION-internal.aliyuncs.com/OSS_PATH/' TBLPROPERTIES ( 'odps.properties.rolearn'='acs:ram::UID:role/aliyunodpsdefaultrole' );读取数据
SELECT * FROM ext_tbl_iceberg_delegate; -- 返回结果 +------------+------+------------+--------+--------+----------+--------------+-------+---------+--------+-------------+-------------+------------+ | id | name | age | gender | height | birthday | phone_number | email | address | salary | create_time | update_time | is_deleted | +------------+------+------------+--------+--------+----------+--------------+-------+---------+--------+-------------+-------------+------------+ | 1 | 张三 | 18 | 男 | 178.56 | 1990-01-01 | 13800000000 | zhangsan@example.com | 北京市海淀区 | 5000 | 2023-04-19 11:32:00 | 2023-04-19 11:32:00 | false | | 2 | 李四 | 20 | 女 | 162.7 | 1992-02-02 | 13900000000 | lisi@example.com | 上海市浦东新区 | 6000 | 2023-04-19 11:32:00 | 2023-04-19 11:32:00 | false | | 3 | 王五 | 22 | 男 | 185.21 | 1994-03-03 | 14000000000 | wangwu@example.com | 深圳市南山区 | 7000 | 2023-04-19 11:32:00 | 2023-04-19 11:32:00 | false | +------------+------+------------+--------+--------+----------+--------------+-------+---------+--------+-------------+-------------+------------+
支持数据类型
Iceberg数据类型详情参考iceberg primitive types。
Iceberg数据类型 | MaxCompute数据类型 |
Types.BooleanType | BOOLEAN |
Types.IntegerType | INT |
Types.LongType | BIGINT |
Types.FloatType | FLOAT |
Types.DoubleType | DOUBLE |
Types.DecimalType | DECIMAL(precision, scale)
|
Types.DateType | DATE |
Types.TimeType | BIGINT
|
Types.TimestampType | TIMESTAMP_NTZ |
Types.TimestampType_z | TIMESTAMP |
Types.StringType | STRING |
Types.UUIDType | BINARY |
Types.FixedType | BINARY |
Types.BinaryType | BINARY |
TypeID.STRUCT | STRUCT |
TypeID.LIST | ARRAY |
TypeID.MAP | MAP |
不涉及 | TINYIN\SMALLINT\VARCHAR(n)\CHAR(n)\DATETIME\JSON |