CREATE HYBRID TABLE¶
在当前/指定架构中创建新的混合表或替换现有表。一个表可以有多个列,每个列定义均涵盖名称、数据类型,以及列是否符合以下条件:
需要一个 NOT NULL 值。
具有默认值或为标识列。
具有任何内联约束。
备注
创建混合表时,您必须在一个列或多个列上定义 PRIMARY KEY 约束。
您还可以使用以下 CREATE TABLE 变体来创建混合表:
:ref:`label-create_hybrid_table_as`(创建一个已填充的表;也称为 CTAS)
:ref:`label-create_hybrid_table_like`(创建现有混合表的空副本)
对于用于标准 Snowflake 表的完整 CREATE TABLE 语法,请参阅 CREATE TABLE。
小技巧
在创建和使用混合表之前,您应该熟悉一些 不支持的功能和限制。
语法¶
CREATE [ OR REPLACE ] HYBRID TABLE [ IF NOT EXISTS ] <table_name>
( <col_name> <col_type>
[
{
DEFAULT <expr>
| { AUTOINCREMENT | IDENTITY }
[
{
( <start_num> , <step_num> )
| START <num> INCREMENT <num>
}
]
[ { ORDER | NOORDER } ]
}
]
[ NOT NULL ]
[ inlineConstraint ]
[ COMMENT '<string_literal>' ]
[ , <col_name> <col_type> [ ... ] ]
[ , outoflineConstraint ]
[ , outoflineIndex ]
[ , ... ]
)
[ COMMENT = '<string_literal>' ]
其中:
inlineConstraint ::= [ CONSTRAINT <constraint_name> ] { UNIQUE | PRIMARY KEY | { [ FOREIGN KEY ] REFERENCES <ref_table_name> [ ( <ref_col_name> ) ] } } [ <constraint_properties> ] 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> ] [ COMMENT '<string_literal>' ] outoflineIndex ::= INDEX <index_name> ( <col_name> [ , <col_name> , ... ] ) [ INCLUDE ( <col_name> [ , <col_name> , ... ] ) ]有关内联和外联约束的详细信息,请参阅 CREATE | ALTER TABLE ... CONSTRAINT。
必填参数¶
name
指定表的标识符(即名称);对于在其中创建表的架构必须唯一。
此外,标识符必须以字母字符开头,且不能包含空格或特殊字符,除非整个标识符字符串放在双引号内(例如,
"My object"
)。放在双引号内的标识符也区分大小写。有关更多信息,请参阅 标识符要求。
col_name
指定列标识符(即名称)。表标识符的所有要求也适用于列标识符。
有关更多详细信息,请参阅 标识符要求 和 保留和受限关键字。
备注
除了标准的保留关键字之外,以下关键字不能用作列标识符,因为它们是为 ANSI 标准上下文函数保留的:
CURRENT_DATE
CURRENT_ROLE
CURRENT_TIME
CURRENT_TIMESTAMP
CURRENT_USER
有关保留关键字的列表,请参阅 保留和受限关键字。
col_type
指定列的数据类型。
有关可为表列指定的数据类型的详细信息,请参阅 SQL 数据类型参考。
PRIMARY KEY ( col_name [ , col_name , ... ] )
可以在列定义中(内联)或单独(外联)指定表所需的主键约束。另请参阅 混合表的约束。
有关完整的语法详细信息,请参阅 CREATE | ALTER TABLE ... CONSTRAINT。有关约束的一般信息,请参阅 约束。
可选参数¶
DEFAULT ...
或 .AUTOINCREMENT ...
指定在未通过 INSERT 或 CREATE HYBRID TABLE AS SELECT 语句明确指定值的情况下,是否自动在列中插入默认值:
DEFAULT expr
使用指定的表达式定义列的默认值,该表达式可以是以下任意项:
常量值。
简单表达式。
序列参考 (
seq_name.NEXTVAL
)。
简单表达式是返回标量值的表达式;但是,该表达式 不能 包含对以下内容的引用:
子查询。
汇总。
窗口函数。
外部函数。
{ AUTOINCREMENT | IDENTITY }
.[ { ( start_num , step_num ) | START num INCREMENT num } ]
.[ { ORDER | NOORDER } ]
当使用
AUTOINCREMENT
时,列的默认值以指定的数字开头,并且每个连续值都会自动生成。AUTOINCREMENT
列生成的值保证是唯一的。任何一对生成的值之间的差都可以保证是增量金额的倍数。可选的
ORDER
和NOORDER
参数指定生成的值是否提供 序列语义 中指定的排序保证。NOORDER
是混合表上的AUTOINCREMENT
列的默认选项。NOORDER
通常为点写入提供明显更好的性能。这些参数只能用于具有数值数据类型的列(NUMBER、INT、FLOAT 等)。
AUTOINCREMENT
和IDENTITY
是同义的。如果为列指定了任一参数,则 Snowflake 将利用序列来生成列的值。有关序列的更多信息,请参阅 使用序列。start 和 step/increment 的默认值均为
1
。
默认值:无值(列没有默认值)
备注
DEFAULT
和AUTOINCREMENT
是互斥的;只能为一列指定一个值。对于性能敏感型工作负载,
NOORDER
是推荐的AUTOINCREMENT
列选项。
CONSTRAINT ...
为表中的指定列定义内联或行外约束。对于混合表列,UNIQUE 和 FOREIGN KEY 约束可选。另请参阅 混合表的约束。
有关完整的语法详细信息,请参阅 CREATE | ALTER TABLE ... CONSTRAINT。有关约束的一般信息,请参阅 约束。
INDEX index_name ( col_name [ , col_name , ... ]
指定表中一个或多个列的二级索引。(当您对混合表列定义约束时,会对这些列自动创建索引。)
无法在以下列上定义索引:
:doc:`半结构化的列 </sql-reference/data-types-semistructured>`(VARIANT、OBJECT、ARRAY),由于与每条记录的键的底层存储引擎关联的空间约束。
地理空间列。
TIMESTAMP_TZ 列(或解析为 TIMESTAMP_TZ 的 TIMESTAMP 列)。支持 TIMESTAMP_NTZ 列。
可以在创建表时定义索引,或使用 CREATE INDEX 命令定义索引。有关创建混合表索引的更多信息,请参阅 CREATE INDEX。
INCLUDE ( col_name [ , col_name , ... ] )
为二级索引指定一个或多个包含的列。当查询包含的一系列列经常在 SELECT 列表但不在 WHERE 谓词列表中时,将包含的列与二级索引一起使用可能特别有用。请参阅 创建一个带有 INCLUDE 列的二级索引。
INCLUDE 列不能是半结构化列(VARIANT、OBJECT、ARRAY)或地理空间列(GEOGRAPHY、GEOMETRY)。
只有在创建带二级索引的表时才能指定 INCLUDE 列。CREATE INDEX 不支持 INCLUDE。
COMMENT = 'string_literal'
指定列、约束或表级别的注释。有关详细信息,请参阅 关于约束的注释。
默认:无值
使用说明¶
要重新创建或替换混合表,请调用 GET_DDL 函数来查看混合表的定义,然后再运行 CREATE OR REPLACE HYBRID TABLE 命令。
您无法创建 临时或瞬态 的混合表。反之,您无法在瞬态架构或数据库中创建混合表。
架构不能包含同名的表和/或视图。创建表时:
如果架构中已存在同名视图,则会返回错误,并且不会创建表。
如果架构中已存在同名的表,则会返回错误,并且不会创建表,除非命令中包含可选的
OR REPLACE
关键字。
重要
使用
OR REPLACE
相当于对现有表执行 DROP TABLE,然后创建具有相同名称的新表。请注意,删除和创建操作发生在单个原子操作中。这意味着与 CREATE OR REPLACE TABLE 操作并行的任何查询都使用旧的或新的表版本。
重新创建表或交换表会删除其更改数据。
OR REPLACE
和IF NOT EXISTS
子句互斥。它们不能同时用于同一条语句中。有关克隆混合表的信息,请参阅 克隆包含混合表的数据库。
与 保留关键字 类似,ANSI 保留函数名称(CURRENT_DATE、CURRENT_TIMESTAMP 等)不能用作列名。
关于元数据:
注意
客户应确保在使用 Snowflake 服务时,不会将个人数据(用户对象除外)、敏感数据、出口管制数据或其他受监管数据作为元数据输入。有关更多信息,请参阅 Snowflake 中的元数据字段。
混合表的约束¶
以下规则适用于在混合表上定义的约束。
必须使用 PRIMARY KEY 约束创建混合表。
支持多列(或复合)主键。要定义多列主键,请使用以下示例中的语法,其中约束是行外约束,并引用之前为表定义的多个列:
CREATE OR REPLACE HYBRID TABLE ht2pk ( col1 INTEGER NOT NULL, col2 INTEGER NOT NULL, col3 VARCHAR, CONSTRAINT pkey_1 PRIMARY KEY (col1, col2) );
PRIMARY KEY、UNIQUE 和 FOREIGN KEY 约束都是在混合表上强制执行,您无法在这些约束上设置 NOT ENFORCED 属性。
PRIMARY KEY、UNIQUE 和 FOREIGN KEY 约束会构建自己的基础索引。索引的创建会导致存储更多数据。在创建表时,也可以使用
outoflineIndex
语法显式定义二级(或覆盖)索引。约束在行级别强制执行,不在语句或事务级别强制执行(即延迟约束)。
约束只能在创建表时定义。
您不能将列更改为 UNIQUE。
以下规则专门适用于 FOREIGN KEY 约束:
混合表中引用主键的外键不能是 NULL。如果您尝试将 NULL 值加载到具有 FOREIGNKEY 约束的列中,则加载操作会因约束错误而失败。请参阅 创建两个具有主键/外键关系的混合表。
仅在属于同一数据库的混合表之间支持 FOREIGN KEY 约束。
只要 FOREIGN KEY 关系存在,就不能截断来自 FOREIGN KEY 约束的引用表。
FOREIGN KEY 约束不支持部分匹配。
FOREIGN KEY 约束不支持可递延行为。
FOREIGN KEY 约束仅支持 DELETE 和 UPDATE 操作的 RESTRICT 和 NO ACTION 属性。
CREATE HYBRID TABLE ...AS SELECT (CTAS)¶
创建新的混合表,其中包含查询的结果:
CREATE [ OR REPLACE ] HYBRID TABLE <table_name> [ ( <col_name> [ <col_type> ] , <col_name> [ <col_type> ] , ... ) ] AS <query> [ ... ]备注
使用 CTAS 创建混合表时,请显式定义表架构,包括列定义、主键、索引和其他约束条件。不要依赖从 SELECT 语句推断架构。
指定的列名称数量必须与查询中的 SELECT 列表项数量匹配。
要以特定顺序创建带有行的表,请在查询末尾使用 ORDER BY 子句。
有关加载混合表的信息,请参阅 加载数据。
CREATE HYBRID TABLE ... LIKE¶
使用与现有混合表相同的列定义创建新的混合表,但不从现有表中复制数据。
列名称、类型、默认值和约束将复制到新表中:
CREATE [ OR REPLACE ] HYBRID TABLE <table_name> LIKE <source_hybrid_table> [ ... ]备注
CREATE HYBRID TABLE ... LIKE 仅支持将另一个混合表作为源表类型。
当前不支持具有通过数据共享访问的自动递增序列的表的 CREATE HYBRID TABLE ... LIKE。
示例¶
在当前数据库中创建一个混合表,以 customer_id
为主键,对 email
具有唯一约束,同时对 full_name
具有二级索引:
CREATE HYBRID TABLE mytable (
customer_id INT AUTOINCREMENT PRIMARY KEY,
full_name VARCHAR(255),
email VARCHAR(255) UNIQUE,
extended_customer_info VARIANT,
INDEX index_full_name (full_name)
);
+-------------------------------------+
| status |
|-------------------------------------|
| Table MYTABLE successfully created. |
+-------------------------------------+
在此表中插入一行:
INSERT INTO mytable (customer_id, full_name, email, extended_customer_info)
SELECT 100, 'Jane Doe', 'jdoe@example.com',
parse_json('{"address": "1234 Main St", "city": "San Francisco", "state": "CA", "zip":"94110"}');
+-------------------------+
| number of rows inserted |
|-------------------------|
| 1 |
+-------------------------+
主键必须是唯一的。例如,如果再次尝试插入上一示例中的相同主键,则命令将失败,并显示以下错误:
200001 (22000): Primary key already exists
电子邮件地址也必须遵循内联 UNIQUE 约束。例如,如果尝试插入具有相同电子邮件地址的两条记录,则语句将失败,并显示以下错误:
Duplicate key value violates unique constraint "SYS_INDEX_MYTABLE_UNIQUE_EMAIL"
查看表属性和元数据。请注意 is_hybrid
列的值:
SHOW TABLES LIKE 'mytable';
+-------------------------------+---------+---------------+-------------+-------+-----------+---------+------------+------+-------+--------+----------------+----------------------+-----------------+---------------------+------------------------------+---------------------------+-------------+
| created_on | name | database_name | schema_name | kind | is_hybrid | comment | cluster_by | rows | bytes | owner | retention_time | automatic_clustering | change_tracking | search_optimization | search_optimization_progress | search_optimization_bytes | is_external |
|-------------------------------+---------+---------------+-------------+-------+-----------+---------+------------+------+-------+--------+----------------+----------------------+-----------------+---------------------+------------------------------+---------------------------+-------------|
| 2022-02-23 23:53:19.707 +0000 | MYTABLE | MYDB | PUBLIC | TABLE | Y | | | NULL | NULL | MYROLE | 10 | OFF | OFF | OFF | NULL | NULL | N |
+-------------------------------+---------+---------------+-------------+-------+-----------+---------+------------+------+-------+--------+----------------+----------------------+-----------------+---------------------+------------------------------+---------------------------+-------------+
查看所有混合表的详细信息:
SHOW HYBRID TABLES;
+-------------------------------+---------------------------+---------------+-------------+--------------+--------------+------+-------+---------+
| created_on | name | database_name | schema_name | owner | datastore_id | rows | bytes | comment |
|-------------------------------+---------------------------+---------------+-------------+--------------+--------------+------+-------+---------|
| 2022-02-24 02:07:31.877 +0000 | MYTABLE | DEMO_DB | PUBLIC | ACCOUNTADMIN | 2002 | NULL | NULL | |
+-------------------------------+---------------------------+---------------+-------------+--------------+--------------+------+-------+---------+
显示有关表中各列的信息:
DESCRIBE TABLE mytable;
+-------------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+
| name | type | kind | null? | default | primary key | unique key | check | expression | comment | policy name |
|-------------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------|
| CUSTOMER_ID | NUMBER(38,0) | COLUMN | N | NULL | Y | N | NULL | NULL | NULL | NULL |
| FULL_NAME | VARCHAR(256) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL |
| APPLICATION_STATE | VARIANT | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL |
+-------------------+--------------+--------+-------+---------+-------------+------------+-------+------------+---------+-------------+
从表中选择数据:
SELECT customer_id, full_name, email, extended_customer_info
FROM mytable
WHERE extended_customer_info['state'] = 'CA';
+-------------+-----------+------------------+------------------------------+
| CUSTOMER_ID | FULL_NAME | EMAIL | EXTENDED_CUSTOMER_INFO |
|-------------+-----------+------------------+------------------------------|
| 100 | Jane Doe | jdoe@example.com | { |
| | | | "address": "1234 Main St", |
| | | | "city": "San Francisco", |
| | | | "state": "CA", |
| | | | "zip": "94110" |
| | | | } |
+-------------+-----------+------------------+------------------------------+
创建两个具有主键/外键关系的混合表¶
此示例显示了如何创建两个相互引用的混合表。第一个表``team`` 在其 team_id
列上有一个 PRIMARY KEY 约束。第二个表 player
在其 team_id
列上有一个 FOREIGN KEY 约束,引用 team
表中的 team_id
列。
CREATE OR REPLACE HYBRID TABLE team
(team_id INT PRIMARY KEY,
team_name VARCHAR(40),
stadium VARCHAR(40));
CREATE OR REPLACE HYBRID TABLE player
(player_id INT PRIMARY KEY,
first_name VARCHAR(40),
last_name VARCHAR(40),
team_id INT,
FOREIGN KEY (team_id) REFERENCES team(team_id));
您可以在两个表中插入一些行,从而验证是否强制执行了参照完整性。您还可以确认定义为外键的列中不允许使用 NULL 值。
第一次向 player
表中插入按预期成功。第二次插入失败,因为 3
不作为 team
表中的 ID 存在。第三次插入失败,因为不允许 NULL 作为外键。
INSERT INTO team VALUES (1, 'Bayern Munich', 'Allianz Arena');
INSERT INTO player VALUES (100, 'Harry', 'Kane', 1);
INSERT INTO player VALUES (301, 'Gareth', 'Bale', 3);
200009 (22000): Foreign key constraint "SYS_INDEX_PLAYER_FOREIGN_KEY_TEAM_ID_TEAM_TEAM_ID" was violated.
INSERT INTO player VALUES (200, 'Tommy', 'Atkins', NULL);
200009 (22000): Foreign key constraint "SYS_INDEX_PLAYER_FOREIGN_KEY_TEAM_ID_TEAM_TEAM_ID" was violated.
SELECT * FROM team t, player p WHERE t.team_id=p.team_id;
+---------+---------------+---------------+-----------+------------+-----------+---------+
| TEAM_ID | TEAM_NAME | STADIUM | PLAYER_ID | FIRST_NAME | LAST_NAME | TEAM_ID |
|---------+---------------+---------------+-----------+------------+-----------+---------|
| 1 | Bayern Munich | Allianz Arena | 100 | Harry | Kane | 1 |
+---------+---------------+---------------+-----------+------------+-----------+---------+
在这种情况下,拒绝 NULL 的可能解决方法是在 team
表(包含一组含 0
的 ID)中插入一个“虚拟”行。然后,您可以将行插入 player
表,该表使用 ``0``(而不是 NULL)的匹配占位符值。例如:
INSERT INTO team VALUES (0, 'Unknown', 'Unknown');
INSERT INTO player VALUES (200, 'Tommy', 'Atkins', 0);
SELECT * FROM team t, player p WHERE t.team_id=p.team_id;
+---------+---------------+---------------+-----------+------------+-----------+---------+
| TEAM_ID | TEAM_NAME | STADIUM | PLAYER_ID | FIRST_NAME | LAST_NAME | TEAM_ID |
|---------+---------------+---------------+-----------+------------+-----------+---------|
| 1 | Bayern Munich | Allianz Arena | 100 | Harry | Kane | 1 |
| 0 | Unknown | Unknown | 200 | Tommy | Atkins | 0 |
+---------+---------------+---------------+-----------+------------+-----------+---------+
创建一个带有 INCLUDE 列的二级索引¶
例如,使用二级索引创建 employee
表:
CREATE HYBRID TABLE employee (
employee_id INT PRIMARY KEY,
employee_name VARCHAR(200),
employee_department VARCHAR(200),
INDEX idx_department (employee_department) INCLUDE (employee_name)
);
插入以下行:
INSERT INTO employee VALUES
(1, 'John Doe', 'Marketing'),
(2, 'Jane Smith', 'Sales'),
(3, 'Bob Johnson', 'Finance'),
(4, 'Alice Brown', 'Marketing');
以下查询将使用二级索引:
SELECT employee_name FROM employee WHERE employee_department = 'Marketing';
SELECT employee_name FROM employee WHERE employee_department IN ('Marketing', 'Sales');
这两个查询都将通过避免基表的查找而从二级索引中获益。但是,请注意,使用索引中包含的列可能会导致存储使用量增加,因为二次索引中还将存储额外的列。
创建一个混合表,并在主键列上添加注释¶
创建一个混合表,其中在主键的列定义中添加注释。
CREATE OR REPLACE HYBRID TABLE ht1pk
(COL1 NUMBER(38,0) NOT NULL COMMENT 'Primary key',
COL2 NUMBER(38,0) NOT NULL,
COL3 VARCHAR(16777216),
CONSTRAINT PKEY_1 PRIMARY KEY (COL1));
DESCRIBE TABLE ht1pk;
+------+-------------------+--------+-------+---------+-------------+------------+-------+------------+-------------+-------------+----------------+
| name | type | kind | null? | default | primary key | unique key | check | expression | comment | policy name | privacy domain |
|------+-------------------+--------+-------+---------+-------------+------------+-------+------------+-------------+-------------+----------------|
| COL1 | NUMBER(38,0) | COLUMN | N | NULL | Y | N | NULL | NULL | Primary key | NULL | NULL |
| COL2 | NUMBER(38,0) | COLUMN | N | NULL | N | N | NULL | NULL | NULL | NULL | NULL |
| COL3 | VARCHAR(16777216) | COLUMN | Y | NULL | N | N | NULL | NULL | NULL | NULL | NULL |
+------+-------------------+--------+-------+---------+-------------+------------+-------+------------+-------------+-------------+----------------+
请注意,如果您将此注释添加至 CONSTRAINT 子句,则该注释在 DESCRIBE TABLE 输出中不可见。您可以查询 TABLE_CONSTRAINTS 视图,查看有关约束的完整信息。