ALTER TABLE
功能
该语句用于修改已有表,包括:
- 修改表名、分区名、索引名、列名
- 修改表注释
- 修改分区(增删分区和修改分区属性)
- 修改分桶方式和分桶数量
- 修改列(增删列和修改列顺序)
- 创建或删除 rollup index
- 修改 bitmap index
- 修改表的属性
- 对表进行原子替换
- 手动执行 compaction 合并表数据
该操作需要有对应表 的 ALTER 权限。
语法
ALTER TABLE 语法格式如下:
ALTER TABLE [<db_name>.]<tbl_name>
alter_clause1[, alter_clause2, ...]
其中 alter_clause 分为 rename、comment、partition、bucket、column、rollup index、bitmap index、table property、swap、compaction 相关修改操作:
- rename: 修改表名、rollup index 名、partition 名或列名(从 3.3.2 版本开始支持)。
- comment: 修改表的注释。从 3.1 版本开始支持。
- partition: 修改分区属性,删除分区,增加分区。
- bucket:修改分桶方式和分桶数量。
- column: 增加列,删除列,调整列顺序,修改列类型。*
- rollup index: 创建或删除 rollup index。
- bitmap index: 修改 bitmap index。
- swap: 原子替换两张表。
- compaction: 对指定表或分区手动执行 Compaction(数据版本合并)。从 3.1 版本开始支持。
使用限制和注意事项
- partition、column 和 rollup index 这些操作不能同时出现在一条
ALTER TABLE
语句中。 - 当前还不支持修改列注释。
- 每张表仅支持一个进行中的 Schema Change 操作。不能对同一张表同时执行两条 Schema Change 命令。
- bucket、column、rollup index 是异步操作,命令提交成功后会立即返回一个成功消息,您可以使用 SHOW ALTER TABLE 语句查看操作的进度。如果需要取消正在进行的操作,则您可以使用 CANCEL ALTER TABLE。
- rename、comment、partition、bitmap index 和 swap 是同步操作,命令返回表示执行完毕。
Rename 对名称进行修改
修改表名
语法:
ALTER TABLE <tbl_name> RENAME <new_tbl_name>;
修改 rollup index 名称 (RENAME ROLLUP)
语法:
ALTER TABLE [<db_name>.]<tbl_name>
RENAME ROLLUP old_rollup_name new_rollup_name;
修改 partition 名称 (RENAME PARTITION)
语法:
ALTER TABLE [<db_name>.]<tbl_name>
RENAME PARTITION <old_partition_name> <new_partition_name>;
修改列名(RENAME COLUMN)
自 v3.3.2 起,StarRocks 支持修改列名。
ALTER TABLE [<db_name>.]<tbl_name>
RENAME COLUMN <old_col_name> [ TO ] <new_col_name>
- 在将某列由 A 重命名为 B 后,不支持继续增加 A 列。
- 在列名变更后,基于该列创建的物化视图将不再生效,您需要根据新的列名重新创建。
修改表的注释(3.1 版本起)
语法:
ALTER TABLE [<db_name>.]<tbl_name> COMMENT = "<new table comment>";
当前还不支持修改列注释。
操作 partition 相关语法
增加分区 (ADD PARTITION(S))
增加分区时支持使用 Range 分区和 List 分区。
语法:
-
Range 分区
ALTER TABLE
ADD { single_range_partition | multi_range_partitions } [distribution_desc] ["key"="value"];
single_range_partition ::=
PARTITION [IF NOT EXISTS] <partition_name> VALUES partition_key_desc
partition_key_desc ::=
{ LESS THAN { MAXVALUE | value_list }
| [ value_list , value_list ) } -- 注意此处的 [ 代表左闭合区间
value_list ::=
( <value> [, ...] )
multi_range_partitions ::=
{ PARTITIONS START ("<start_date_value>") END ("<end_date_value>") EVERY ( INTERVAL <N> <time_unit> )
| PARTITIONS START ("<start_integer_value>") END ("<end_integer_value>") EVERY ( <granularity> ) } -- 即使 START、END 所指定的分区列值为整数,也需要使用英文引号包裹,而 EVERY 子句中的分区增量值不用英文引号包裹。 -
List 分区
ALTER TABLE
ADD PARTITION <partition_name> VALUES IN (value_list) [distribution_desc] ["key"="value"];
value_list ::=
value_item [, ...]
value_item ::=
{ <value> | ( <value> [, ...] ) }
参数:
-
分区相关参数
- Range 分区支持新增单个分区
single_range_partition
或者批量创建分区multi_range_partition
。 - List 分区仅支持新增单个分区。
- Range 分区支持新增单个分区
-
distribution_desc
:可以为新的分区单独设置分桶数量,但是不支持单独设置分桶方式。
-
"key"="value"
:可以为新的分区设置属性,具体说明见 CREATE TABLE。
示例:
-
Range 分区
-
如果建表时指定分区列为
event_day
,例如PARTITION BY RANGE(event_day)
,并且建表后需要新增一个分区,则可以执行:ALTER TABLE site_access ADD PARTITION p4 VALUES LESS THAN ("2020-04-30");
-
如果建表时指定分区列为
datekey
,例如PARTITION BY RANGE (datekey)
,并且建表后需要批量新增多个分区,则可以执行:ALTER TABLE site_access
ADD PARTITIONS START ("2021-01-05") END ("2021-01-10") EVERY (INTERVAL 1 DAY);
-
-
List 分区
-
如果建表时指定单个分区列,例如
PARTITION BY LIST (city)
,并且建表后需要新增一个分区,则可以执行:ALTER TABLE t_recharge_detail2
ADD PARTITION pCalifornia VALUES IN ("Los Angeles","San Francisco","San Diego"); -
如果建表时指定多个分区列,例如
PARTITION BY LIST (dt,city)
,并且建表后需要新增一个分区,则可以执行:ALTER TABLE t_recharge_detail4
ADD PARTITION p202204_California VALUES IN
(
("2022-04-01", "Los Angeles"),
("2022-04-01", "San Francisco"),
("2022-04-02", "Los Angeles"),
("2022-04-02", "San Francisco")
);
-
删除分区 (DROP PARTITION(S))
删除单个分区:
ALTER TABLE [<db_name>.]<tbl_name>
DROP PARTITION [ IF EXISTS ] <partition_name> [ FORCE ]
批量删除分区(自 v3.3.1 起支持):
ALTER TABLE [<db_name>.]<tbl_name>
DROP [ TEMPORARY ] PARTITIONS [ IF EXISTS ] { partition_name_list | multi_range_partitions } [ FORCE ]
partion_name_list ::= ( <partition_name> [, ... ] )
multi_range_partitions ::=
{ START ("<start_date_value>") END ("<end_date_value>") EVERY ( INTERVAL <N> <time_unit> )
| START ("<start_integer_value>") END ("<end_integer_value>") EVERY ( <granularity> ) } -- 即使 START、END 所指定的分区列值为整数,也需要使用英文引号包裹,而 EVERY 子句中的分区增量值不用英文引号包裹。
关于 multi_range_partitions
的说明:
multi_range_partitions
仅适用于 Range 分区。- 其中涉及的参数与 增加分区 ADD PARTITION(S) 中的相同。
- 仅支持基于单个分区键的分区。
- 分区表需要至少要保留一个分区。
- 如果未指定 FORCE 关键字,您可以通过 RECOVER 语句恢复一定时间范围内(默认 1 天)删除的分区。
- 如果指定了 FORCE 关键字,则系统不会检查该分区是否存在未完成的事务,分区将直接被删除并且不能被恢复,一般不建议执行此操作。
增加临时分区 (ADD TEMPORARY PARTITION)
详细使用信息,请查阅临时分区。
语法:
ALTER TABLE [<db_name>.]<tbl_name>
ADD TEMPORARY PARTITION [IF NOT EXISTS] <partition_name>
partition_desc ["key"="value"]
[DISTRIBUTED BY HASH (k1[,k2 ...]) [BUCKETS num]];
使用临时分区替换原分区
语法:
ALTER TABLE [<db_name>.]<tbl_name>
REPLACE PARTITION <partition_name>
partition_desc ["key"="value"]
WITH TEMPORARY PARTITION
partition_desc ["key"="value"]
[PROPERTIES ("key"="value", ...)]
删除临时分区 (DROP TEMPORARY PARTITION)
语法:
ALTER TABLE [<db_name>.]<tbl_name>
DROP TEMPORARY PARTITION <partition_name>;
修改分区属性 (MODIFY PARTITION)
语法:
ALTER TABLE [<db_name>.]<tbl_name>
MODIFY PARTITION { <partition_name> | partition_name_list | (*) }
SET ("key" = "value", ...);
使用说明:
-
当前支持修改分区的下列属性:
- storage_medium
- storage_cooldown_ttl 或 storage_cooldown_time
- replication_num
-
对于单分区表,分区名同表名。对于多分区表,如果需要修改所有分区的属性,则使用
(*)
更加方便。 -
执行
SHOW PARTITIONS FROM <tbl_name>
查看修改后分区属性。
修改分桶方式和分桶数量(自 3.2 版本起)
语法:
ALTER TABLE [<db_name>.]<table_name>
[ partition_names ]
[ distribution_desc ]
partition_names ::=
(PARTITION | PARTITIONS) ( <partition_name> [, <partition_name> ...] )
distribution_desc ::=
DISTRIBUTED BY RANDOM [ BUCKETS <num> ] |
DISTRIBUTED BY HASH ( <column_name> [, <column_name> ...] ) [ BUCKETS <num> ]
示例:
假设原表为明细表,分桶方式为 Hash 分桶,分桶数量为自动设置。
CREATE TABLE IF NOT EXISTS details (
event_time DATETIME NOT NULL COMMENT "datetime of event",
event_type INT NOT NULL COMMENT "type of event",
user_id INT COMMENT "id of user",
device_code INT COMMENT "device code",
channel INT COMMENT ""
)
DUPLICATE KEY(event_time, event_type)
PARTITION BY date_trunc('day', event_time)
DISTRIBUTED BY HASH(user_id);
-- 插入多天的数据
INSERT INTO details (event_time, event_type, user_id, device_code, channel) VALUES
-- 11 月 26 日的数据
('2023-11-26 08:00:00', 1, 101, 12345, 2),
('2023-11-26 09:15:00', 2, 102, 54321, 3),
('2023-11-26 10:30:00', 1, 103, 98765, 1),
-- 11 月 27 日的数据
('2023-11-27 08:30:00', 1, 104, 11111, 2),
('2023-11-27 09:45:00', 2, 105, 22222, 3),
('2023-11-27 11:00:00', 1, 106, 33333, 1),
-- 11 月 28 日的数据
('2023-11-28 08:00:00', 1, 107, 44444, 2),
('2023-11-28 09:15:00', 2, 108, 55555, 3),
('2023-11-28 10:30:00', 1, 109, 66666, 1);
仅修改分桶方式
注意
- 修改分桶方式针对整个表的所有分区生效,不能仅仅针对某个分区生效。
- 虽然仅修改分桶方式,没有修改分桶数量,但是您仍然需要在语句中说明分桶数量
BUCKETS <num>
,如果不指定,则表示由 StarRocks 自动设置分桶数量。
-
将原先的 Hash 分桶修改为 Random 分桶,并且分桶数量仍然由 StarRocks 自动设置。
ALTER TABLE details DISTRIBUTED BY RANDOM;
-
将 Hash 分桶时所使用的分桶键从原先的
event_time, event_type
修改为user_id, event_time
。并且分桶数量仍然由 StarRocks 自动设置。ALTER TABLE details DISTRIBUTED BY HASH(user_id, event_time);
仅修改分桶数量
注意
虽然仅修改分桶数量,没有修改分桶方式,但是您仍然需要在语句中说明分桶方式,例如示例中的
HASH(user_id)
。
-
将所有分区的分桶数量从原先的由 StarRocks 自动设置修改为 10。
ALTER TABLE details DISTRIBUTED BY HASH(user_id) BUCKETS 10;
-
将指定分区的分桶数量从原先的由 StarRocks 自动设置修改为 15。
ALTER TABLE details PARTITIONS (p20231127, p20231128) DISTRIBUTED BY HASH(user_id) BUCKETS 15;
说明
分区名称可以执行
SHOW PARTITIONS FROM <table_name>;
进行查看。
同时修改分桶方式和分桶数量
注意
同时修改分桶方式和分桶数量针对整个表的所有分区生效,不能仅仅针对某个分区生效。
-
分桶方式从原先的 Hash 分桶修改为 Random 分桶,并且分桶数量从原先的由 StarRocks 自动设置修改为 10。
ALTER TABLE details DISTRIBUTED BY RANDOM BUCKETS 10;
-
将 Hash 分桶时所使用的分桶键从原先的
event_time, event_type
修改为user_id, event_time
,并且分桶数量从原先的由 StarRocks 自动设置修改为 10。ALTER TABLE details DISTRIBUTED BY HASH(user_id, event_time) BUCKETS 10;