CREATE ICEBERG TABLE(使用 Snowflake 作为 Iceberg 目录)¶
在当前/指定架构中,创建或替换 将 Snowflake 用作 Iceberg 目录 的 Apache Iceberg™ 表。
该命令支持以下变体:
CREATE ICEBERG TABLE ...AS SELECT(创建一个已填充的表;也称为 CTAS)
CREATE ICEBERG TABLE ...LIKE (创建现有表的空副本)
本主题将 Iceberg 表简称为“表”(指定 Iceberg 表 的位置除外)以避免混淆。
- 另请参阅:
ALTER ICEBERG TABLE、DROP ICEBERG TABLE、SHOW ICEBERG TABLES、DESCRIBE ICEBERG TABLE、UNDROP ICEBERG TABLE
语法¶
CREATE [ OR REPLACE ] ICEBERG TABLE [ IF NOT EXISTS ] <table_name> (
-- Column definition
<col_name> <col_type>
[ inlineConstraint ]
[ NOT NULL ]
[ { DEFAULT <expr>
| { AUTOINCREMENT | IDENTITY }
[ { ( <start_num> , <step_num> )
| START <num> INCREMENT <num>
} ]
} ]
[ [ WITH ] MASKING POLICY <policy_name> [ USING ( <col_name> , <cond_col1> , ... ) ] ]
[ [ WITH ] PROJECTION POLICY <policy_name> ]
[ [ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] ) ]
[ COMMENT '<string_literal>' ]
-- Additional column definitions
[ , <col_name> <col_type> [ ... ] ]
-- Out-of-line constraints
[ , outoflineConstraint [ ... ] ]
)
[ CLUSTER BY ( <expr> [ , <expr> , ... ] ) ]
[ EXTERNAL_VOLUME = '<external_volume_name>' ]
[ CATALOG = 'SNOWFLAKE' ]
BASE_LOCATION = '<directory_for_table_files>'
[ CATALOG_SYNC = '<open_catalog_integration_name>']
[ STORAGE_SERIALIZATION_POLICY = { COMPATIBLE | OPTIMIZED } ]
[ DATA_RETENTION_TIME_IN_DAYS = <integer> ]
[ MAX_DATA_EXTENSION_TIME_IN_DAYS = <integer> ]
[ CHANGE_TRACKING = { TRUE | FALSE } ]
[ COPY GRANTS ]
[ COMMENT = '<string_literal>' ]
[ [ WITH ] ROW ACCESS POLICY <policy_name> ON ( <col_name> [ , <col_name> ... ] ) ]
[ [ WITH ] AGGREGATION POLICY <policy_name> ]
[ [ WITH ] TAG ( <tag_name> = '<tag_value>' [ , <tag_name> = '<tag_value>' , ... ] ) ]
其中:
inlineConstraint ::= [ CONSTRAINT <constraint_name> ] { UNIQUE | PRIMARY KEY | [ FOREIGN KEY ] REFERENCES <ref_table_name> [ ( <ref_col_name> ) ] } [ <constraint_properties> ]有关其他内联约束的详细信息,请参阅 CREATE | ALTER TABLE ...CONSTRAINT。
outoflineConstraint ::= [ CONSTRAINT <constraint_name> ] { UNIQUE [ ( <col_name> [ , <col_name> , ... ] ) ] | PRIMARY KEY [ ( <col_name> [ , <col_name> , ... ] ) ] | [ FOREIGN KEY ] [ ( <col_name> [ , <col_name> , ... ] ) ] REFERENCES <ref_table_name> [ ( <ref_col_name> [ , <ref_col_name> , ... ] ) ] } [ <constraint_properties> ]备注
Snowflake 表示定义为 PRIMARY KEY 的列,作为 Iceberg 元数据中的标识符字段。这些列的 IDs 在元数据中填充为 标识符字段 IDs (https://iceberg.apache.org/spec/#identifier-field-ids)。
Snowflake 不对 Iceberg 表的 PRIMARY KEY 列强制执行 NOT NULL 和 UNIQUE 约束条件。
有关其他行外约束的详细信息,请参阅 CREATE | ALTER TABLE ...CONSTRAINT。
变体语法¶
CREATE ICEBERG TABLE ...AS SELECT(也称为 CTAS)¶
创建一个新表,其中填充了查询返回的数据。将 AS SELECT 子句放在语句末尾。
CREATE [ OR REPLACE ] ICEBERG TABLE <table_name> [ ( <col_name> [ <col_type> ] , <col_name> [ <col_type> ] , ... ) ] [ CLUSTER BY ( <expr> [ , <expr> , ... ] ) ] [ EXTERNAL_VOLUME = '<external_volume_name>' ] [ CATALOG = 'SNOWFLAKE' ] BASE_LOCATION = '<relative_path_from_external_volume>' [ COPY GRANTS ] [ ... ] AS SELECT <query>
掩码策略可以应用于 CTAS 语句中的列。先指定列数据类型,然后指定掩码策略。同样,可以将行访问策略应用于表。例如:
CREATE ICEBERG TABLE <table_name> ( <col1> <data_type> [ WITH ] MASKING POLICY <policy_name> [ , ... ] ) [ EXTERNAL_VOLUME = '<external_volume_name>' ] [ CATALOG = 'SNOWFLAKE' ] BASE_LOCATION = '<directory_for_table_files>' [ WITH ] ROW ACCESS POLICY <policy_name> ON ( <col1> [ , ... ] ) [ ... ] AS SELECT <query>
备注
在 CTAS 中,COPY GRANTS 参数仅在与 OR REPLACE 子句组合时才有效。COPY GRANTS 从要使用 CREATE OR REPLACE 替换的表(如果已存在)中复制权限,而不是从 SELECT 语句中查询的源表中复制权限。通过具有 COPY GRANTS 的 CTAS,您可以使用一组新数据覆盖表,同时将现有授权保留在该表上。
有关 COPY GRANTS 参数的更多信息,请参阅本文档中的 COPY GRANTS。
有关该变体语法的更多信息,请参阅 使用说明。
CREATE ICEBERG TABLE ... LIKE¶
使用与现有表相同的列定义创建新表,但不从现有表中复制数据。列名称、类型、默认值和约束将复制到新表中:
CREATE [ OR REPLACE ] ICEBERG TABLE <table_name> LIKE <source_table> [ CLUSTER BY ( <expr> [ , <expr> , ... ] ) ] [ COPY GRANTS ] [ ... ]
有关 COPY GRANTS 参数的更多信息,请参阅本文档中的 COPY GRANTS。
备注
CREATE TABLE ...LIKE 不支持用于具有通过数据共享访问的自动递增序列的表。
有关该变体语法的更多信息,请参阅 使用说明。
CREATE ICEBERG TABLE ... CLONE¶
创建具有相同的列定义的新 Iceberg 表,并包含源表中的全部现有数据,而不会实际复制数据。您还可以利用此变体克隆过去的特定时间/点的表(使用 Time Travel):
CREATE [ OR REPLACE ] ICEBERG TABLE [ IF NOT EXISTS ] <name> CLONE <source_iceberg_table> [ { AT | BEFORE } ( { TIMESTAMP => <timestamp> | OFFSET => <time_difference> | STATEMENT => <id> } ) ] [COPY GRANTS] ...
备注
如果该语句用于替换同名的现有 Iceberg 表,Snowflake 会从要替换的表中复制授权。如果没有该名称的现有表,Snowflake 会从要克隆的源表中复制授权。
有关 COPY GRANTS 参数的更多信息,请参阅本文档中的 COPY GRANTS。
有关克隆的更多信息,请参阅 CREATE <object> ...CLONE 和 克隆和 Apache Iceberg™ 表。
必填参数¶
table_name
指定表的标识符(名称);在创建表的架构中必须是唯一的。
此外,标识符必须以字母字符开头,且不能包含空格或特殊字符,除非整个标识符字符串放在双引号内(例如,
"My object"
)。放在双引号内的标识符也区分大小写。有关更多信息,请参阅 标识符要求。
col_name
指定列标识符(名称)。表标识符的所有要求也适用于列标识符。
备注
除了标准的保留关键字之外,以下关键字不能用作列标识符,因为它们是为 ANSI 标准上下文函数保留的:
CURRENT_DATE
CURRENT_ROLE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
有关保留关键字的列表,请参阅 保留和受限关键字。
col_type
指定列的数据类型。
有关可为表列指定的数据类型的信息,请参阅 Apache Iceberg™ 表的数据类型。
备注
您不能使用
float
或double
作为主键(根据 ` Apache Iceberg 规范 <https://iceberg.apache.org/spec/#identifier-field-ids (https://iceberg.apache.org/spec/#identifier-field-ids)>`_)。BASE_LOCATION = 'directory_for_table_files'
Snowflake 可在其中写入表的数据和元数据文件所在目录的路径。指定从表
EXTERNAL_VOLUME
的位置开始的相对路径。有关更多信息,请参阅 数据和元数据目录。创建表后,此目录无法更改。
可选参数¶
CONSTRAINT ...
为表中的指定列定义内联或行外约束。
有关语法信息,请参阅 CREATE | ALTER TABLE ...CONSTRAINT。有关约束条件的更多信息,请参阅 约束。
DEFAULT ...
或 .AUTOINCREMENT ...
指定在未通过 INSERT 或 CREATE TABLE AS SELECT 语句明确指定值的情况下,是否自动在列中插入默认值:
DEFAULT expr
使用指定的表达式定义列的默认值,该表达式可以是以下任意项:
常量值。
序列参考 (
seq_name.NEXTVAL
)。返回标量值的简单表达式。
如果 UDF 不是 安全 UDF,简单表达式可能包括 SQL UDF(用户定义函数)。
备注
如果默认表达式引用 SQL UDF,则在创建表时将函数替换为函数定义。如果在将来重新定义用户定义函数,则不会更新列的默认表达式。
简单表达式 不能 包含对以下内容的引用:
子查询。
汇总。
窗口函数。
安全 UDFs。
用 SQL 以外的语言编写的 UDFs(例如 Java、JavaScript)。
外部函数。
- {
AUTOINCREMENT
|IDENTITY
} [ {( start_num , step_num )
|START num INCREMENT num
} ] AUTOINCREMENT
和IDENTITY
是同义的。当使用任一值时,列的默认值以指定的数字开头,并且每个连续值都会自动按指定的量递增。小心
Snowflake 使用序列来生成自动递增列的值。序列存在局限性;请参阅 序列语义。
start 和 step/increment 的默认值均为
1
。AUTOINCREMENT
和IDENTITY
只能用于具有数值数据类型的列。
默认值:无值(列没有默认值)
备注
DEFAULT
和AUTOINCREMENT
是互斥的;只能为一列指定一个值。MASKING POLICY = policy_name
指定要在列上设置的 掩码策略。
PROJECTION POLICY policy_name
指定要在列上设置的 投影策略。
COMMENT 'string_literal'
指定列的注释。
(请注意,可以在列级别或表级别指定注释。相应的语法略有不同。)
USING ( col_name , cond_col_1 ... )
指定要传递到条件掩码策略的 SQL 表达式的实参。
列表中的第一列指定用于掩码处理或标记数据的策略条件的列,并且 必须 与设置掩码策略的列匹配。
附加列指定要评估的列,以确定查询从第一列进行选择时是否对查询结果的每行中的数据进行掩码处理或标记化。
如果省略 USING 子句,Snowflake 会将条件掩码策略视为正常的 掩码策略。
CLUSTER BY ( expr [ , expr , ... ] )
将表中的一个或多个列或列表达式指定为群集密钥。有关更多信息,请参阅 群集密钥和聚类表。
默认:无值(未为表定义群集密钥)
EXTERNAL_VOLUME = 'external_volume_name'
指定外部卷的标识符(名称),Iceberg 表会以 Parquet 格式将自身的元数据文件和数据存储在里面。Iceberg 元数据和清单文件存储表架构、分区、快照和其他元数据。
如果未指定此参数,则 Iceberg 表将默认使用架构、数据库或账户的外部卷。架构优先于数据库,数据库优先于账户。
CATALOG = 'SNOWFLAKE'
指定 Snowflake 作为 Iceberg 目录Snowflake 处理表的全部生命周期维护工作,例如压缩。
CATALOG_SYNC = 'open_catalog_integration_name'
(可选)指定为 Snowflake Open 目录 配置的目录集成的名称。如果指定,Snowflake 会将表与 Snowflake Open Catalog 账户中的外部目录同步。有关更多信息,请参阅 将 Snowflake 管理的表与 Snowflake Open Catalog 同步。
STORAGE_SERIALIZATION_POLICY = { COMPATIBLE | OPTIMIZED }
为表指定存储序列化策略。如果在创建表时未指定,表将继承在架构、数据库或账户级别设置的值。如果在任何级别均未指定该值,表将使用默认值。
创建表后,此参数的值无法更改。
COMPATIBLE
:Snowflake 执行编码和压缩,确保与第三方计算引擎的互操作性。OPTIMIZED
:Snowflake 执行编码和压缩,可确保 Snowflake 中的最佳表性能。
默认:
OPTIMIZED
DATA_RETENTION_TIME_IN_DAYS = integer
指定由 Snowflake 管理的表的保留期,以便可以对表中的历史数据执行 Time Travel 操作(SELECT、CLONE、UNDROP)。有关更多信息,请参阅 了解和使用 Time Travel。
有关此对象级参数的详细说明以及有关对象参数的详细信息,请参阅 参数。
值:
Standard Edition:
0
或1
Enterprise Edition:
0
至90
用于永久表
默认:
Standard Edition:
1
Enterprise Edition(或更高版本):
1
(除非在架构、数据库或账户级别指定了不同的默认值)
备注
0
值实际上会为表禁用 Time Travel。
MAX_DATA_EXTENSION_TIME_IN_DAYS = integer
对象参数,指定 Snowflake 可以延长表的数据保留期以防止表上的流过时的最大天数。
有关此参数的详细说明,请参阅 MAX_DATA_EXTENSION_TIME_IN_DAYS。
CHANGE_TRACKING = { TRUE | FALSE }
指定是否对表启用变更跟踪。
TRUE
在表上启用变更跟踪。此设置将一对隐藏列添加到源表中,并开始在列中存储变更跟踪元数据。这些列会占用少量存储空间。可以使用 SELECT 语句的 CHANGES 子句查询变更跟踪元数据,也可以通过在表上创建和查询一个或多个流来查询变更跟踪元数据。
FALSE
不在表上启用变更跟踪。
默认:FALSE
COPY GRANTS
指定在使用以下 CREATE TABLE 变体创建新表时保留原始表的访问权限:
CREATE OR REPLACE TABLE
CREATE TABLE ...LIKE
CREATE TABLE ...CLONE
该参数将 除 OWNERSHIP 之外的所有权限从现有表复制到新表。新表 不会 继承为架构中的对象类型定义的任何未来授权。默认情况下,执行 CREATE TABLE 语句的角色拥有新表。
如果该参数未包含在 CREATE ICEBERG TABLE 语句中,则新表 不会 继承在原始表上授予的任何显式访问权限,但会继承为架构中的对象类型定义的任何未来授权。
注意:
借助 数据共享:
如果现有表已共享到另一个账户,则替换表也会共享。
如果现有表已作为数据使用者与您的账户共享,并且进一步授予了对账户中其他角色的访问权限(在父数据库上使用
GRANT IMPORTED PRIVILEGES
),则还会授予对替换表的访问权限。
替换表的 SHOW GRANTS 输出会将复制权限的获得者列为执行 CREATE ICEBERG TABLE 语句的角色,并附带执行语句时的当前时间戳。
复制授权的操作在 CREATE ICEBERG TABLE 命令中会以原子方式发生(即在同一事务中)。
COMMENT = 'string_literal'
指定注释。您可在列级别或表级别指定注释。每个级别的语法略有不同。
默认:无值
ROW ACCESS POLICY policy_name ON ( col_name [ , col_name ... ] )
指定要在表上设置的 行访问策略。
AGGREGATION POLICY policy_name
指定要在表上设置的 聚合策略。
访问控制要求¶
权限 |
对象 |
备注 |
---|---|---|
CREATE ICEBERG TABLE |
架构 |
|
CREATE EXTERNAL VOLUME |
账户 |
需要创建新的外部卷。 |
USAGE |
外部卷 |
需要引用现有的外部卷。 |
请注意,对架构中的对象进行操作还需要对父数据库和架构具有 USAGE 权限。
有关创建具有指定权限集的自定义角色的说明,请参阅 创建自定义角色。
使用说明¶
运行此命令的注意事项:
使用 Snowflake 作为 Iceberg 目录时,目前不支持跨云和跨区域的 Iceberg 表。如果 CREATE ICEBERG TABLE 返回类似
"External volume <volume_name> must have a STORAGE_LOCATION defined in the local region ..."
的错误消息,请确保您的外部卷使用与 Snowflake 账户位于同一区域的活动存储位置。如果您使用双引号标识符创建了外部卷,则必须 完全 按照在 CREATE ICEBERG TABLE 语句中创建的标识符(包括双引号)来指定标识符。未包含引号可能会导致
Object does not exist
错误(或类似类型的错误)。若要查看示例,请参阅 ` 示例 `_ (本主题内容)部分。
不支持使用 USING TEMPLATE 子句(以及从 INFER_SCHEMA 输出派生的列定义)创建 Iceberg 表。
创建表的注意事项:
架构不能包含同名的表和/或视图。创建表时:
如果架构中已存在同名视图,则会返回错误,并且不会创建表。
如果架构中已存在同名的表,则会返回错误,并且不会创建表,除非命令中包含可选的
OR REPLACE
关键字。
CREATE OR REPLACE <object> 语句是原子的。也就是说,当对象被替换时,旧对象将被删除,新对象将在单个事务中创建。
这意味着与 CREATE OR REPLACE ICEBERG TABLE 操作并行的任何查询都使用旧的或新的表版本。
与 保留关键字 类似,ANSI 保留函数名称(CURRENT_DATE、CURRENT_TIMESTAMP 等)不能用作列名。
重新创建表(使用可选
OR REPLACE
关键字)会删除其历史记录,这会使表上的任何流都过时。过时的流是不可读的。
使用变体语法:
CREATE ICEBERG TABLE ... LIKE:
如果来源表具有群集密钥,则新表具有群集密钥。默认情况下,即使来源表的自动聚类已暂停,新表的自动聚类也不会暂停。
CREATE ICEBERG TABLE ...AS SELECT (CTAS):
在 CTAS 语句中指定群集密钥时:
列定义是必需的,必须在语句中明确指定。
默认情况下,即使来源表的自动聚类已暂停,新表的自动聚类也不会暂停。
如果希望使用特定顺序的行创建表,请在 CTAS 的 SELECT 子句中使用 ORDER BY 分子句。指定 CLUSTER BY 不会在创建表时对数据进行聚类; CLUSTER BY 会依赖于 自动聚类 来随着时间的推移重聚类数据。
CREATE TABLE 语句中的 ORDER BY 分子句不会影响将来的 SELECT 语句返回该表的行顺序。若要指定将来 SELECT 语句中的行顺序,请在这些语句中使用 ORDER BY 分子句。
关于元数据:
注意
客户应确保在使用 Snowflake 服务时,不会将个人数据(用户对象除外)、敏感数据、出口管制数据或其他受监管数据作为元数据输入。有关更多信息,请参阅 Snowflake 中的元数据字段。
如果要创建将与 Snowflake Open Catalog 同步的表,请谨记以下几点:
重要
要确保在 Open Catalog 中对表正确实施特权,请确保在创建表之前满足特定条件。这些条件与目录的目录结构层次结构有关。有关这些条件以及如何满足这些条件的说明,请参阅 Snowflake Open Catalog 文档中 组织目录内容 中的说明。
要排查创建 Snowflake 管理的表的问题,请参阅 您无法创建 Snowflake 管理的表。
示例¶
创建以 Snowflake 作为目录的 Iceberg 表¶
此示例创建以 Snowflake 作为 Iceberg 目录的 Iceberg 表。生成的表由 Snowflake 管理,并支持读写访问。
该示例将表名称 (my_iceberg_table
) 设置为 BASE_LOCATION
。这样,Snowflake 就会将数据和元数据写入到与外部卷位置中的表同名的目录。
CREATE ICEBERG TABLE my_iceberg_table (amount int)
CATALOG = 'SNOWFLAKE'
EXTERNAL_VOLUME = 'my_external_volume'
BASE_LOCATION = 'my_iceberg_table';
使用 CTAS 变体语法创建 Iceberg 表¶
此示例使用 CREATE ICEBERG TABLE ...AS SELECT 变体语法,从名为 base_iceberg_table
的表创建 新 Iceberg 表。AS SELECT 子句必须位于语句末尾。
CREATE OR REPLACE ICEBERG TABLE iceberg_table_copy (column1 int)
EXTERNAL_VOLUME = 'my_external_volume'
CATALOG = 'SNOWFLAKE'
BASE_LOCATION = 'iceberg_table_copy'
AS SELECT * FROM base_iceberg_table;
使用双引号标识符指定外部卷¶
此示例创建一个具有外部卷的 Iceberg 表,表的标识符中包含双引号。放在双引号内的标识符区分大小写,并且通常包含特殊字符。
标识符 "external_volume_1"
指定为与创建时完全相同(包括双引号)。未包含引号可能会导致 Object does not exist
错误(或类似类型的错误)。
要了解更多信息,请参阅 加双引号的标识符。
CREATE OR REPLACE ICEBERG TABLE table_with_quoted_external_volume
EXTERNAL_VOLUME = '"external_volume_1"'
CATALOG = 'SNOWFLAKE'
BASE_LOCATION = 'my/relative/path/from/external_volume';