CREATE TABLE
在 StarRocks 中创建一个新表。
此操作需要对目标数据库具有 CREATE TABLE 权限。
语法
CREATE [EXTERNAL] [TEMPORARY] TABLE [IF NOT EXISTS] [database.]table_name
(column_definition1[, column_definition2, ...]
[, index_definition1[, index_definition12,]])
[ENGINE = [olap|mysql|elasticsearch|hive|hudi|iceberg|jdbc]]
[key_desc]
[COMMENT "table comment"]
[partition_desc]
[distribution_desc]
[rollup_index]
[ORDER BY (column_name1,...)]
[PROPERTIES ("key"="value", ...)]
关键字
EXTERNAL
EXTERNAL 关键字已弃用。
我们建议您使用 external catalogs 从 Hive、Iceberg、Hudi 和 JDBC 数据源查询数据,而不是使用 EXTERNAL 关键字创建外部表。
推荐
从 v3.1 开始,StarRocks 支持在 Iceberg catalogs 中创建 Parquet 格式的表,并支持使用 INSERT INTO 将数据写入这些 Parquet 格式的 Iceberg 表。
从 v3.2 开始,StarRocks 支持在 Hive catalogs 中创建 Parquet 格式的表,并支持使用 INSERT INTO 将数据写入这些 Parquet 格式的 Hive 表。从 v3.3 开始,StarRocks 支持在 Hive catalogs 中创建 ORC 和 Textfile 格式的表,并支持使用 INSERT INTO 将数据写入这些 ORC 和 Textfile 格式的 Hive 表。
如果您想使用已弃用的 EXTERNAL 关键字,请展开 EXTERNAL 关键字详情
EXTERNAL 关键字详情
要创建一个外部表以查询外部数据源,请指定 CREATE EXTERNAL TABLE 并将 ENGINE 设置为以下任一值。您可以参考 External table 了解更多信息。
-
对于 MySQL 外部表,指定以下属性:
PROPERTIES (
"host" = "mysql_server_host",
"port" = "mysql_server_port",
"user" = "your_user_name",
"password" = "your_password",
"database" = "database_name",
"table" = "table_name"
)注意:
MySQL 中的 "table_name" 应指示实际的表名。相反,CREATE TABLE 语句中的 "table_name" 指示此 MySQL 表在 StarRocks 中的名称。它们可以不同也可以相同。
在 StarRocks 中创建 MySQL 表的目的是访问 MySQL 数据库。StarRocks 本身不维护或存储任何 MySQL 数据。
-
对于 Elasticsearch 外部表,指定以下属性:
PROPERTIES (
"hosts" = "http://192.168.xx.xx:8200,http://192.168.xx0.xx:8200",
"user" = "root",
"password" = "root",
"index" = "tindex",
"type" = "doc"
)hosts: 用于连接您的 Elasticsearch 集群的 URL。您可以指定一个或多个 URL。user: 用于登录启用了基本身份验证的 Elasticsearch 集群的 root 用户的账户。password: 上述 root 账户的密码。index: StarRocks 表在您的 Elasticsearch 集群中的索引。索引名称与 StarRocks 表名称相同。您可以将此参数设置为 StarRocks 表的别名。type: 索引的类型。默认值为doc。
-
对于 Hive 外部表,指定以下属性:
PROPERTIES (
"database" = "hive_db_name",
"table" = "hive_table_name",
"hive.metastore.uris" = "thrift://xx.xx.xx.xx:9083"
)这里,database 是 Hive 表中对应数据库的名称。table 是 Hive 表的名称。
hive.metastore.uris是服务器地址。 -
对于 JDBC 外部表,指定以下属性:
PROPERTIES (
"resource"="jdbc0",
"table"="dest_tbl"
)resource是 JDBC 资源名称,table是目标表。 -
对于 Iceberg 外部表,指定 以下属性:
PROPERTIES (
"resource" = "iceberg0",
"database" = "iceberg",
"table" = "iceberg_table"
)resource是 Iceberg 资源名称。database是 Iceberg 数据库。table是 Iceberg 表。 -
对于 Hudi 外部表,指定以下属性:
PROPERTIES (
"resource" = "hudi0",
"database" = "hudi",
"table" = "hudi_table"
)
TEMPORARY
创建一个临时表。从 v3.3.1 开始,StarRocks 支持在 Default Catalog 中创建临时表。有关更多信息,请参见 Temporary Table。
创建临时表时,必须将 ENGINE 设置为 olap。
column_definition
col_name col_type [agg_type] [NULL | NOT NULL] [DEFAULT "default_value"] [AUTO_INCREMENT] [AS generation_expr]
col_name
请注意,通常您不能创建以 __op 或 __row 开头的列名,因为这些名称格式在 StarRocks 中保留用于特殊用途,创建此类列可能会导致未定义的行为。如果您确实需要创建此类列,请将 FE 动态参数 allow_system_reserved_names 设置为 TRUE。
col_type
特定列信息,例如类型和范围:
-
TINYINT (1 字节):范围从 -2^7 + 1 到 2^7 - 1。
-
SMALLINT (2 字节):范围从 -2^15 + 1 到 2^15 - 1。
-
INT (4 字节):范围从 -2^31 + 1 到 2^31 - 1。
-
BIGINT (8 字节):范围从 -2^63 + 1 到 2^63 - 1。
-
LARGEINT (16 字节):范围从 -2^127 + 1 到 2^127 - 1。
-
FLOAT (4 字节):支持科学计数法。
-
DOUBLE (8 字节):支持科学计数法。
-
DECIMAL[(precision, scale)] (16 字节)
-
默认值:DECIMAL(10, 0)
-
precision: 1 ~ 38
-
scale: 0 ~ precision
-
整数部分:precision - scale
不支持科学计数法。
-
-
DATE (3 字节):范围从 0000-01-01 到 9999-12-31。
-
DATETIME (8 字节):范围从 0000-01-01 00:00:00 到 9999-12-31 23:59:59。
-
CHAR[(length)]:固定长度字符串。范围:1 ~ 255。默认值:1。
-
VARCHAR[(length)]:可变长度字符串。默认值为 1。单位:字节。在 StarRocks 2.1 之前的版本中,
length的值范围为 1–65533。[预览] 在 StarRocks 2.1 及更高版本中,length的值范围为 1–1048576。 -
HLL (1~16385 字节):对于 HLL 类型,无需指定长度或默认值。长度将根据数据聚合在系统内控制。HLL 列只能通过 hll_union_agg、Hll_cardinality 和 hll_hash 查询或使用。
-
BITMAP:Bitmap 类型不需要指定长度或默认值。它表示一组无符号 bigint 数字。最大元素可以达到 2^64 - 1。
agg_type
聚合类型。如果未指定,则此列为键列。 如果指定,则为值列。支持的聚合类型如下:
SUM、MAX、MIN、REPLACEHLL_UNION(仅适用于HLL类型)BITMAP_UNION(仅适用于BITMAP)REPLACE_IF_NOT_NULL:这意味着只有在导入的数据为非空值时才会替换。如果为 null 值,StarRocks 将保留原始值。
- 当导入聚合类型为 BITMAP_UNION 的列时,其原始数据类型必须为 TINYINT、SMALLINT、INT 和 BIGINT。
- 如果在创建表时为 REPLACE_IF_NOT_NULL 列指定了 NOT NULL,StarRocks 仍会将数据转换为 NULL 而不会向用户发送错误报告。这样,用户可以选择性地导入列。
此聚合类型仅适用于键描述类型为 AGGREGATE KEY 的聚合表。自 v3.1.9 起,REPLACE_IF_NOT_NULL 新增支持 BITMAP 类型的列。
NULL | NOT NULL:列是否允许为 NULL。默认情况下,表中使用明细表、聚合表或更新表的所有列都指定为 NULL。在使用主键表的表中,默认情况下,值列指定为 NULL,而键列指定为 NOT NULL。如果原始数据中包含 NULL 值,请使用 \N 表示。在数据导入期间,StarRocks 将 \N 视为 NULL。
DEFAULT "default_value":列的默认值。当您将数据导入 StarRocks 时,如果映射到该列的源字段为空,StarRocks 会自动在该列中填充默认值。您可以通过以下方式之一指定默认值:
- DEFAULT current_timestamp:使用当前时间作为默认值。有关更多信息,请参见 current_timestamp()。
- DEFAULT
<default_value>:使用列数据类型的给定值作为默认值。例如,如果列的数据类型为 VARCHAR,您可以指定一个 VARCHAR 字符串,例如 beijing,作为默认值,如DEFAULT "beijing"所示。请注意,默认值不能是以下类型之一:ARRAY、BITMAP、JSON、HLL 和 BOOLEAN。 - DEFAULT (<expr>):使用给定函数返回的结果作为默认值。仅支持 uuid() 和 uuid_numeric() 表达式。
AUTO_INCREMENT:指定一个 AUTO_INCREMENT 列。AUTO_INCREMENT 列的数据类型必须为 BIGINT。自增 ID 从 1 开始,步长为 1。有关 AUTO_INCREMENT 列的更多信息,请参见 AUTO_INCREMENT。自 v3.0 起,StarRocks 支持 AUTO_INCREMENT 列。
AS generation_expr:指定生成列及其表达式。生成列 可用于预计算和存储表达式的结果,这显著加速了具有相同复杂表达式的查询。自 v3.1 起,StarRocks 支持生成列。
index_definition
INDEX index_name (col_name[, col_name, ...]) [USING BITMAP] COMMENT 'xxxxxx'
有关参数描述和使用注意事项的更多信息,请参见 Bitmap 索引。
ENGINE
默认值:olap。如果未指定此参数,则默认创建 OLAP 表(StarRocks 内表)。
可选值:mysql、elasticsearch、hive、jdbc、iceberg 和 hudi。
Key
语法:
key_type(k1[,k2 ...])
数据按指定的键列排序,并且不同的键类型具有不同的属性:
-
AGGREGATE KEY:键列中的相同内容将根据指定的聚合类型聚合到值列中。通常适用于财务报表和多维分析等业务场景。
-
UNIQUE KEY/PRIMARY KEY:键列中的相同内容将根据导入顺序在值列中替换。可以应用于对键列进行增、删、改、查。
-
DUPLICATE KEY:键列中的相同内容同时存在于 StarRocks 中。可用于存储明细数据或无聚合属性的数据。
备注DUPLICATE KEY 是默认类型。数据将根据键列排序。
当使用其他 key_type 创建表时,值列不需要指定聚合类型,AGGREGATE KEY 除外。
COMMENT
您可以在创建表时添加表注释,选填。请注意,COMMENT 必须放在 key_desc 之后。否则,无法创建表。
从 v3.1 开始,您可以使用 ALTER TABLE <table_name> COMMENT = "new table comment" 修改表注释。
分区
可以通过以下方式管理分区:
动态创建分区
动态分区 提供了分区的生存时间 (TTL) 管理。StarRocks 自动提前创建新分区并删除过期分区,以确保数据的新鲜度。要启用此功能,您可以在创建表时配置动态分区相关属性。
逐个创建分区
仅为分区指定上限
语法:
PARTITION BY RANGE ( <partitioning_column1> [, <partitioning_column2>, ... ] )
PARTITION <partition1_name> VALUES LESS THAN ("<upper_bound_for_partitioning_column1>" [ , "<upper_bound_for_partitioning_column2>", ... ] )
[ ,
PARTITION <partition2_name> VALUES LESS THAN ("<upper_bound_for_partitioning_column1>" [ , "<upper_bound_for_partitioning_column2>", ... ] )
, ... ]
)
请使用指定的键列和指定的值范围进行分区。
-
有关分区命名约定,请参见 系统限制。
-
在 v3.3.0 之前,范围分区的列仅支持以下类型:TINYINT、SMALLINT、INT、BIGINT、LARGEINT、DATE 和 DATETIME。自 v3.3.0 起,三种特定时间函数可以用作范围分区的列。有关详细用法,请参见 数据分布。
-
分区是左闭右开的。第一个分区的左边界为最小值。
-
NULL 值仅存储在包含最小值的分区中。当删除包含最小值的分区时,无法再导入 NULL 值。
-
分区列可以是单列或多列。分区值为默认最小值。
-
当仅指定一个列作为分区列时,可以将
MAXVALUE设置为最近分区的分区列的上限。PARTITION BY RANGE (pay_dt) (
PARTITION p1 VALUES LESS THAN ("20210102"),
PARTITION p2 VALUES LESS THAN ("20210103"),
PARTITION p3 VALUES LESS THAN MAXVALUE
)
- 分区通常用于管理与时间相关的数据。
- 当需要数据回溯时,您可能需要 考虑清空第一个分区,以便在必要时添加分区。
为分区指定上下限
语法:
PARTITION BY RANGE ( <partitioning_column1> [, <partitioning_column2>, ... ] )
(
PARTITION <partition_name1> VALUES [( "<lower_bound_for_partitioning_column1>" [ , "<lower_bound_for_partitioning_column2>", ... ] ), ( "<upper_bound_for_partitioning_column1?" [ , "<upper_bound_for_partitioning_column2>", ... ] ) )
[,
PARTITION <partition_name2> VALUES [( "<lower_bound_for_partitioning_column1>" [ , "<lower_bound_for_partitioning_column2>", ... ] ), ( "<upper_bound_for_partitioning_column1>" [ , "<upper_bound_for_partitioning_column2>", ... ] ) )
, ...]
)
- 指定上下限的方式比 LESS THAN 更灵活。您可以自定义左右分区。
- 指定上下限的方式在其他方面与 LESS THAN 相同。
- 当仅指定一个列作为分区列时,可以将
MAXVALUE设置为最近分区的分区列的上限。
PARTITION BY RANGE (pay_dt) (
PARTITION p202101 VALUES [("20210101"), ("20210201")),
PARTITION p202102 VALUES [("20210201"), ("20210301")),
PARTITION p202103 VALUES [("20210301"), (MAXVALUE))
)
批量创建多个分区
语法
-
如果分区列是日期类型。
PARTITION BY RANGE (<partitioning_column>) (
START ("<start_date>") END ("<end_date>") EVERY (INTERVAL <N> <time_unit>)
) -
如果分区列是整数类型。
PARTITION BY RANGE (<partitioning_column>) (
START ("<start_integer>") END ("<end_integer>") EVERY (<partitioning_granularity>)
)
描述
您可以在 START() 和 END() 中指定起始和结束值,并在 EVERY() 中指定时间单位或分区粒度,以批量创建多个分区。
- 在 v3.3.0 之前,范围分区的列仅支持以下类型:TINYINT、SMALLINT、INT、BIGINT、LARGEINT、DATE 和 DATETIME。自 v3.3.0 起,三种特定时间函数可以用作范围分区的列。有关详细用法,请参见 数据分布。
- 如果分区列是日期类型,则需要使用
INTERVAL关键字指定时间间隔。您可以将时间单位指定为小时(自 v3.0 起)、天、周、月或年。分区的命名约定与动态分区相同。
有关更多信息,请参见 数据分布。
数据分布
StarRocks 支持哈希分桶和随机分桶。如果您不配置分桶,StarRocks 默认使用随机分桶并自动设置桶的数量。
-
随机分桶(自 v3.1 起)
对于分区中的数据,StarRocks 将数据随机分布在所有桶中,而不是基于特定的列值。如果您希望 StarRocks 自动设置桶的数量,则无需指定任何分桶配置。如果您选择手动指定桶的数量,语法如下:
DISTRIBUTED BY RANDOM BUCKETS <num>但是,请注意,当您查询大量数据并频繁使用某些列作为条件列时,随机分桶提供的查询性能可能不理想。在这种情况下,建议使用哈希分桶。因为只需扫描和计算少量桶,从而显著提高查询性能。
注意事项
- 您只能使用随机分桶创建明细表。
- 您不能为随机分桶的表指定 Colocation Group。
- Spark Load 不能用于将数据导入随机分桶的表。
- 自 StarRocks v2.5.7 起,创建表时无需设置桶的数量。StarRocks 会自动设置桶的数量。如果您 想设置此参数,请参见 设置桶的数量。
有关更多信息,请参见 随机分桶。
-
哈希分桶
语法:
DISTRIBUTED BY HASH (k1[,k2 ...]) [BUCKETS num]分区中的数据可以根据分桶列的哈希值和桶的数量细分为多个桶。我们建议您选择满足以下两个要求的列作为分桶列。
- 高基数列,例 如 ID
- 经常在查询中用作过滤器的列
如果不存在这样的列,您可以根据查询的复杂性确定分桶列。
- 如果查询复杂,建议选择高基数列作为分桶列,以确保桶之间的数据分布均衡,提高集群资源利用率。
- 如果查询相对简单,建议选择经常用作查询条件的列作为分桶列,以提高查询效率。
如果使用一个分桶列无法将分区数据均匀分布到每个桶中,您可以选择多个分桶列(最多三个)。有关更多信息,请参见 选择分桶列。
注意事项:
- 创建表时,必须指定其分桶列。
- 分桶列的值不能更新。
- 指定后,分桶列不能修改。
- 自 StarRocks v2.5.7 起,创建表时无需设置桶的数量。StarRocks 会自动设置桶的数量。如果您想设置此参数,请参见 设置桶的数量。
Rollup 索引
您可以在创建表时批量创建 rollup。
语法:
ROLLUP (rollup_name (column_name1, column_name2, ...)
[FROM from_index_name]
[PROPERTIES ("key"="value", ...)],...)
ORDER BY
自 v3.0 起,主键表支持使用 ORDER BY 定义排序键。自 v3.3 起,明细表、聚合表和更新表支持使用 ORDER BY 定义排序键。
有关排序键的更多描述,请参见 排序键和前缀索引。
PROPERTIES
存储和副本
如果引擎类型为 OLAP,您可以在创建表时指定初始存储介质(storage_medium)、自动存储降冷时间(storage_cooldown_time)或时间间隔(storage_cooldown_ttl)以及副本数量(replication_num)。
属性生效的范围:如果表只有一个分区,则属性属于表。如果表分为多个分区,则属性属于每个分区。当您需要为指定分区配置不同的属性时,可以在创建表后执行 ALTER TABLE ... ADD PARTITION 或 ALTER TABLE ... MODIFY PARTITION。