让我们在Iceberg Catalog中创建第一个数据库:
%%sql
CREATE DATABASE IF NOT EXISTS ${ICEBERG_DB}
执行完成后刷新glue的页面,会发现一个新的database被创建出来:
创建数据库后,我们可以开始使用原始客户表中的数据创建表。我们将使用此表探索Iceberg的基本功能。
%%sql
CREATE TABLE ${ICEBERG_DB}.${ICEBERG_CUSTOMER_TABLE} (
c_customer_sk INT COMMENT '唯一ID',
c_customer_id STRING,
c_first_name STRING,
c_last_name STRING,
c_email_address STRING
) USING iceberg
TBLPROPERTIES (
'format-version'='2'
)
COMMENT '此表包含客户数据'
USING iceberg
表示创建的表将采用 Iceberg 表格式进行存储和管理,而不是默认的 Spark 内部表格式或其他格式(如 Parquet、ORC、Delta 等)。format-version='2'
:指定使用 Iceberg 格式版本 2,这是较新的版本执行完成后,在glue里可以找到新的table:
使用以下命令验证数据库中的新表,但请注意,目前表中没有数据。
%%sql
SHOW TABLES IN ${ICEBERG_DB}
使用DESCRIBE查询检查详细的表信息。
%%sql
DESCRIBE TABLE EXTENDED ${ICEBERG_DB}.${ICEBERG_CUSTOMER_TABLE}
使用SHOW TBLPROPERTIES检查表属性。
%%sql
SHOW TBLPROPERTIES ${ICEBERG_DB}.${ICEBERG_CUSTOMER_TABLE}
下图解释了Iceberg 的架构,主要分为三层:
顶层 - Iceberg Catalog (目录层)
db1.table1
的引用, “current metadata pointer”(当前元数据指针),指向最新的有效元数据文件中间层 - Metadata Layer (元数据层)
底层 - Data Layer (数据层)
通过快照(snapshots)实现表的time travel和历史版本访问, 通过更新catalog中的元数据指针来实现原子操作
客户表目前不包含任何数据。因此,metadata文件夹中只有一个元数据文件。一旦插入一些数据,将看到一个data文件夹,用于保存数据文件。
show_tables_files(ICEBERG_CUSTOMER_TABLE)
Glue Data Catalog保存指向最新元数据文件*metadata.json的指针。
show_current_metadata_pointer(ICEBERG_CUSTOMER_TABLE)
以下是元数据文件内容。它存储schema和表属性。目前没有任何快照(snapshots字段是一个空列表):
show_current_metadata_file(ICEBERG_CUSTOMER_TABLE)
{
"format-version" : 2,
"table-uuid" : "bd83cf61-c9d2-4ab0-985d-0824cc5b9f29",
"location" : "s3://otfs-workshop-data-145197526627/datasets/emr_iceberg/emr_iceberg_db.db/customer_iceberg",
"last-sequence-number" : 0,
"last-updated-ms" : 1741784399945,
"last-column-id" : 5,
"current-schema-id" : 0,
"schemas" : [ {
"type" : "struct",
"schema-id" : 0,
"fields" : [ {
"id" : 1,
"name" : "c_customer_sk",
"required" : false,
"type" : "int",
"doc" : "unique id"
}, {
"id" : 2,
"name" : "c_customer_id",
"required" : false,
"type" : "string"
}, {
"id" : 3,
"name" : "c_first_name",
"required" : false,
"type" : "string"
}, {
"id" : 4,
"name" : "c_last_name",
"required" : false,
"type" : "string"
}, {
"id" : 5,
"name" : "c_email_address",
"required" : false,
"type" : "string"
} ]
} ],
"default-spec-id" : 0,
"partition-specs" : [ {
"spec-id" : 0,
"fields" : [ ]
} ],
"last-partition-id" : 999,
"default-sort-order-id" : 0,
"sort-orders" : [ {
"order-id" : 0,
"fields" : [ ]
} ],
"properties" : {
"owner" : "hadoop",
"comment" : "This table contains customer data",
"write.parquet.compression-codec" : "zstd"
},
"current-snapshot-id" : -1,
"refs" : { },
"snapshots" : [ ],
"statistics" : [ ],
"snapshot-log" : [ ],
"metadata-log" : [ ]
}