CREATE TABLE 语句用于创建新表并指定其所有属性。
在创建表时,您可以根据需要指定以下关键方面:
表的类型:内表还是外表,区别参见内表和外表说明。
表的结构:列名、数据类型、注释、约束。
表的物理组织:分区和排序策略。
对于外表:数据文件的存储格式和位置。
注意:
如果要使用与 TCHouse-X 保留关键字相同的数据库、表、列或视图名称,请务必使用反引号 (
``) 将该标识符括起来。创建内表
CREATE TABLE
内表是 TCHouse-X 默认创建的表类型,由 TCHouse-X 完全管理底层数据文件。执行 DROP TABLE 时,数据文件也会被物理删除。
语法
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name(col_name data_type [constraint_specification] [COMMENT 'col_comment'] [, ...])[PARTITIONED BY SPEC partition_clause][SORT BY ([column [, column ...]])][COMMENT 'table_comment']
语法说明
关键字/参数 | 说明 |
IF NOT EXISTS | 可选。如果表已存在,则使用此选项可以避免抛出错误。语句会成功执行,但会发出一个警告。 |
db_name | 可选。若未指定,则默认使用当前会话连接的数据库。 |
table_name | 必需。要创建的表的名称。 |
column_name | 必选。为表的列指定名称。 |
data_type | 必选。为表的列指定类型。 |
COMMENT 'col_comment' | 可选。为表的列添加描述性注释。 |
属性详解
表约束 (constraint_specification)
constraint_specification:PRIMARY KEY (col_name, ...)
当前支持: 内表目前仅支持主键约束 (
PRIMARY KEY)。限制: 不支持
FLOAT 和 DOUBLE 类型的列作为主键,BOOLEAN 不能单独作为主键。分区和分桶 (PARTITIONED BY SPEC)
内表使用
PARTITIONED BY SPEC 子句创建分区表,支持分区和分桶两种方式。partition_clause:column_name -- 仅分区| BUCKET(bucket_number, column_name) -- 分桶
目的: TCHouse-X 利用定义的分区和分桶键,对数据文件进行物理组织。查询时可利用分区元数据,仅扫描匹配的分区,尤其在关联查询时能显著减少 I/O。
分区限制:
TIMESTAMP/TIMESTAMPTZ、TIMESTAMPNTZ 类型的列不能作为分区键分桶限制 (BUCKET):
只能指定一个列作为分桶键。
BOOLEAN、FLOAT、DOUBLE 类型的列不能作为分桶键。如果表定义了主键,则该主键必须包含分桶键。
排序 (SORT BY)
使用
SORT BY 子句定义表数据在存储时按照指定字段进行有序存储。效益: 排序后,数据文件内部记录的列最小/最大值分布更集中。TCHouse-X 可根据
WHERE 条件快速跳过不包含目标范围的文件,并提升数据存储的编码和压缩效果。默认行为:
如果定义了主键,但未指定排序键,则默认使用主键作为排序键。
如果主键和排序键都未指定,则没有排序键。
如果没有显示指定分桶键,则默认以下为分桶键:
如果指定了主键,则主键为分桶键
如果没有主键,则默认为随机分桶
示例
-- 创建非主键表CREATE TABLE test_simple(c1 int, c2 string);-- 创建按 c2 和 c3 分区的非主键表CREATE TABLE test_partitioned(c1 int, c2 string, c3 string)PARTITIONED BY SPEC (c2, c3);-- 创建分区、分桶并排序的表:按 c2 分区,按 c3 分桶,按 c1 排序CREATE TABLE test_all(c1 int, c2 string, c3 string, c4 date)PARTITIONED BY SPEC (c2, BUCKET(16, c3))SORT BY(c1);-- 创建单列主键表CREATE TABLE test_pk_simple(c1 int primary key, c2 string);-- 创建复合主键表CREATE TABLE test_pk_composite(c1 int, c2 string, c3 int, primary key(c1, c3));-- 创建包含主键、分区、分桶和排序的复杂内表CREATE TABLE test_pk_complex(c1 int, c2 string, c3 string, c4 date, primary key(c1,c2))PARTITIONED BY SPEC(c3, BUCKET(16, c1))SORT BY(c4);
CREATE TABLE AS SELECT
CREATE TABLE AS SELECT(简称 CTAS)是一种高效的简写语法。它允许您基于另一个查询的结果创建一张新表,并同时将源数据复制到新表中,从而省去了单独执行 INSERT 语句的步骤。功能
CTAS 可用于以下目的:复制表结构和数据: 快速克隆现有表。
创建数据子集: 使用
WHERE 子句仅复制满足特定条件的行。转换和清洗数据: 在
SELECT 语句中应用函数、连接和表达式来转换数据。动态分区: 根据源表查询结果的列值来定义新表的分区。
语法
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name[PRIMARY KEY (col_name [, ...])][PARTITIONED BY SPEC partition_clause][SORT BY ([column [, column ...]])][COMMENT 'table_comment']ASselect_statement
语法说明
关键字/参数 | 说明 |
IF NOT EXISTS | 可选。如果表已存在,则使用此选项可以避免抛出错误。语句会成功执行,但会发出一个警告。 |
db_name | 可选。若未指定,则默认使用当前会话连接的数据库。 |
table_name | 必需。要创建的表的名称。 |
PRIMARY KEY | 可选。新表指定主键。 |
PARTITIONED BY SPEC | 可选。新表指定分区键。 |
SORT BY | 可选。新表指定排序键。 |
COMMENT 'table_comment' | 可选。为表添加描述性注释。 |
select_statement |
注意:
列名继承:新创建的表会继承 SELECT 语句结果集的列名。您可以使用列别名(AS new_name)来覆盖它们。
元数据继承:原表的列注释和表注释不会被带到新表中。
原子性:
CTAS 不是原子操作。 它实际分两步执行:
1.
CREATE TABLE2.
INSERT INTO SELECT如果
INSERT INTO 步骤失败,只会回滚 INSERT INTO 操作,而 CREATE TABLE 语句依然是成功的。示例
以下示例演示了
CTAS 的各种用法,包括数据复制、转换和动态分区创建。-- 准备源表数据CREATE TABLE t1 (x INT, y STRING);INSERT INTO t1 VALUES (1, 'one'), (2, 'two'), (3, 'three');-- 1. 克隆所有列和数据 (全量复制)CREATE TABLE clone_of_t1 ASSELECT * FROM t1;-- 2. 按条件复制行 (创建子集)CREATE TABLE subset_of_t1 ASSELECT * FROM t1 WHERE x >= 2;-- 3. 只克隆表结构,不复制数据 (空表克隆)CREATE TABLE empty_clone_of_t1 ASSELECT * FROM t1 WHERE 1=0;-- 4. 重新组织、重命名列并转换数据CREATE TABLE t5 ASSELECTupper(y) AS s, -- 数据转换和重命名x+1 AS a, -- 表达式计算'Entirely new column' AS n -- 插入新的常量列FROM t1;SELECT * FROM t5;/*+-------+---+---------------------+| s | a | n |+-------+---+---------------------+| ONE | 2 | Entirely new column || TWO | 3 | Entirely new column || THREE | 4 | Entirely new column |+-------+---+---------------------+*/-- 5. 基于源数据创建分区表CREATE TABLE partitions_no (year smallint, month tinyint, s string);INSERT INTO partitions_no VALUES(2016, 1, 'January 2016'),(2016, 2, 'February 2016'),(2016, 3, 'March 2016');-- 创建一个新表,并使用源表中的 year 和 month 列作为分区键CREATE TABLE partitions_yes PARTITIONED BY SPEC (year, month)AS SELECT s, year, month FROM partitions_no;
CREATE TABLE LIKE
核心功能
克隆结构: 新创建的表会继承源表的完整结构,包括列定义、数据类型、主键、分区规范、排序属性以及所有相关的注释。
创建空表: 此语句不会复制源表中的任何数据。
语法
CREATE TABLE [IF NOT EXISTS] [target_db_name.]target_table_nameLIKE [source_db_name.]source_table_name[COMMENT 'table_comment'];
关键字说明
关键字/参数 | 说明 |
IF NOT EXISTS | 可选。如果表已存在,则避免抛出错误。 |
target_db_name | 可选。目标表的 database 名,若未指定,则默认使用当前会话连接的数据库。 |
target_table_name | 必选。目标表的 table 名 |
LIKE { ... } | 必需。 指定结构来源:一个已存在的 TCHouse-X 表。 |
source_db_name | 可选。源表的 database 名,若未指定,则默认使用当前会话连接的数据库。 |
source_table_name | 必选。源表的 table 名 |
COMMENT | 可选。唯一支持的附加子句。 用于为新表添加或覆盖表级注释。 |
注意:
如果需要在一次操作中同时克隆表结构和复制数据,请使用
CREATE TABLE AS SELECT (CTAS) 语法。示例
以下示例演示了如何创建一个继承现有表结构的新表,并为其添加注释。
-- 1. 创建源表,包含主键、分区和排序属性CREATE TABLE test_source(c1 int, c2 string, PRIMARY KEY(c1))PARTITIONED BY SPEC(c2)SORT BY(c1);-- 2. 使用 LIKE 创建一个空表 test2,继承 test_source 的所有结构属性,并指定一个新的注释CREATE TABLE test2 LIKE test_sourceCOMMENT 'This is a clone of the structure of test_source.';
创建外表
外表 (External Table) 的数据文件通常在 TCHouse-X 外部管理和存储。TCHouse-X 提供了对这些外部数据的查询能力,但不支持修改外部数据(如
INSERT, UPDATE, DELETE)。TCHouse-X 目前支持两种主要的外部表类型:Hive 外表和 Iceberg 外表。
Hive 外表
Hive 外表用于访问存储在 HDFS 或兼容文件系统上的传统 Hive 格式数据(如 Parquet、Textfile)。
语法
CREATE EXTERNAL TABLE [IF NOT EXISTS] [db_name.]table_name(col_name data_type [COMMENT 'col_comment'] [, ...])[PARTITIONED BY partition_clause][SORT BY ([column [, column ...]])][COMMENT 'table_comment'][ROW FORMAT row_format]STORED AS file_formatLOCATION 'table_path'partition_clause(col_name data_type, [, ...])row_format:DELIMITED [FIELDS TERMINATED BY 'char' [ESCAPED BY 'char']] [LINES TERMINATED BY 'char']file_format:PARQUET| TEXTFILE
关键字说明
关键字 | 详细定义 | 适用性/说明 |
PARTITIONED BY | (col_name data_type, [, ...]) | Hive 外表的分区列需在主列定义后单独指定。 |
STORED AS | PARQUET | 仅支持 PARQUET、TEXTFILE |
ROW FORMAT | DELIMITED ... | 仅对 TEXTFILE 文件格式有效,用于指定字段和行分隔符。 |
LOCATION | 'table_path' | 数据文件在文件系统上的绝对路径。 |
对于 TEXTFILE 如果数据文件包含 header, 可以通过 skip.header.line.count 表属性,跳过 header 的解析,比如 csv 文件内容如下:
TINYINT,SMALLINT,INT,BIGINT,BOOLEAN,FLOAT,DOUBLE,DECIMAL,STRING,CHAR,VARCHAR,TIMESTAMP1,100,1000,1000000,true,3.14,3.1415926535,123.456,Hello World,A,Short Text,2023-10-10 12:34:562,200,2000,2000000,false,2.71,2.7182818284,654.321,Data Lake,B,Longer Text,2023-10-11 13:45:003,300,3000,3000000,true,1.23,1.2345678901,789.123,Big Data,C,Very Long Text,2023-10-12 14:56:30
建表语句如下:
CREATE EXTERNAL TABLE text_t (a TINYINT,b SMALLINT, c INT, d BIGINT,e BOOLEAN,f FLOAT,g DOUBLE,h DECIMAL(10,4),i STRING,j CHAR(30),k VARCHAR(30),l TIMESTAMP)ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' STORED AS textfile LOCATION 'cosn://douglaspeng-cq-1375622477/shawbozhang_external_table/text_t'TBLPROPERTIES ('skip.header.line.count'='1');
Iceberg 外表
Iceberg 外表用于访问遵循 Apache Iceberg 规范的表。TCHouse-X 支持 Iceberg 的 v1 和 v2 格式,并且目前支持基于 Hadoop 的两种 Catalog 类型和 Hive 的 Catalog 类型。
语法
CREATE EXTERNAL TABLE [IF NOT EXISTS] [db_name.]table_name[COMMENT 'table_comment']STORED AS ICEBERG[LOCATION 'table_path'][TBLPROPERTIES ('key1'='value1', 'key2'='value2', ...)]
HadoopTables 模式
适用于 Iceberg 表的元数据文件(metadata)位于文件系统中的某个特定位置。
示例
CREATE EXTERNAL TABLE ice_hadoop_tblSTORED AS ICEBERGLOCATION '/path/to/table'TBLPROPERTIES('iceberg.catalog'='hadoop.tables');
示例说明
LOCATION 字段:指定包含 Iceberg 表元数据(如 metadata 文件夹)的路径'iceberg.catalog' 属性:需设置为 'hadoop.tables'HadoopCatalog 模式
适用于 Iceberg 表存储在一个公共的目录位置下,并使用命名空间 (namespace) 和表标识符 (table identifier) 来引用。
示例
CREATE EXTERNAL TABLE ice_hadoop_catSTORED AS ICEBERGTBLPROPERTIES('iceberg.catalog'='hadoop.catalog','iceberg.catalog_location'='/path/to/catalog','iceberg.table_identifier'='namespace.table');
示例属性说明
属性 | 说明 |
iceberg.catalog | 设置为 'hadoop.catalog'。 |
iceberg.catalog_location | 指定 Iceberg Catalog 存储的根目录位置。 |
iceberg.table_identifier | 使用 namespace.table 格式指定表标识符。 |
HiveCatalog 模式
适用于 Iceberg 表的 catalog 为 hive 类型的 Iceberg 表。
示例
CREATE EXTERNAL TABLE ice_hive_cat STORED AS ICEBERGTBLPROPERTIES ('iceberg.catalog'='hive.catalog','hive.metastore.uris'='thrift://127.0.0.1:9083','metastore.catalog.default'='hive','fs.defaultFS'='cosn://cos_bucket','iceberg.table_identifier'='namespace.table');
示例属性说明
属性 | 说明 |
iceberg.catalog | 设置为 'hive.catalog'。 |
hive.metastore.uris | 指定 Hive metastore 的 uris。 |
metastore.catalog.default | 指定 Iceberg 表在 hive 中的 catalog,一般默认在'hive'中。 |
fs.defaultFS | 指定 Iceberg 表数据所在的文件系统,目前只支持 COS,格式: cosn://cos_bucket_name |
iceberg.table_identifier | 使用 namespace.table 格式指定表标识符。 |