clickhouse的alter列操作解析
ALTER
ALTER
仅支持 *MergeTree
,Merge
以及Distributed
等引擎表。 该操作有多种形式。
列操作
改变表结构:
ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ...
在语句中,配置一个或多个用逗号分隔的动作。每个动作是对某个列实施的操作行为。
支持下列动作:
- ADD COLUMN — 添加列
- DROP COLUMN — 删除列
- CLEAR COLUMN — 重置列的值
- COMMENT COLUMN — 给列增加注释说明
- MODIFY COLUMN — 改变列的值类型,默认表达式以及TTL
这些动作将在下文中进行详述。
增加列
ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [codec] [AFTER name_after]
使用指定的name
, type
, codec
以及 default_expr
(请参见 Default expressions),往表中增加新的列。
如果sql中包含 IF NOT EXISTS
,执行语句时如果列已经存在,CH不会报错。如果指定AFTER name_after
(表中另一个列的名称),则新的列会加在指定列的后面。否则,新的列将被添加到表的末尾。注意,不能将新的列添加到表的开始位置, name_after
可以是执行该动作时已经在表中存在的任意列。
添加列仅仅是改变原有表的结构不会对已有数据产生影响。执行完 ALTER
后磁盘中也不会出现新的数据。如果查询表时列的数据为空,那么CH会使用列的默认值来进行填充(如果有默认表达式,则使用这个;或者用0或空字符串)。当数据块完成合并(参见MergeTree)后,磁盘中会出现该列的数据。
这种方式允许 ALTER
语句能马上执行。不需要增加原有数据的大小。
示例:
ALTER TABLE visits ADD COLUMN browser String AFTER user_id
删除列
DROP COLUMN [IF EXISTS] name
通过指定 name
删除列。如果语句包含 IF EXISTS
,执行时遇到不存在的列也不会报错。
从文件系统中删除数据。由于是删除列的整个文件,该语句几乎是立即执行完成的。
示例:
ALTER TABLE visits DROP COLUMN browser
清空列
CLEAR COLUMN [IF EXISTS] name IN PARTITION partition_name
重置指定分区中列的值。 分区名称 partition_name
请参见 怎样设置分区表达式
如果语句中包含 IF EXISTS
,遇到不存在的列,sql执行不会报错。
示例:
ALTER TABLE visits CLEAR COLUMN browser IN PARTITION tuple()
增加注释
COMMENT COLUMN [IF EXISTS] name 'comment'
给列增加注释说明。如果语句中包含 IF EXISTS
,遇到不存在的列,sql执行不会报错。
每个列都可以包含注释。如果列的注释已经存在,新的注释会替换旧的。 注释信息保存在 DESCRIBE TABLE查询的 comment_expression
字段中。
示例:
ALTER TABLE visits COMMENT COLUMN browser 'The table shows the browser used for accessing the site.'
修改列
MODIFY COLUMN [IF EXISTS] name [type] [default_expr] [TTL]
该语句可以改变 name
列的属性:
- Type
- Default expression
- TTL
有关修改列TTL的示例,请参见 Column TTL.
如果语句中包含 IF EXISTS
,遇到不存在的列,sql执行不会报错。
当改变列的类型时,列的值也被转换了,如同对列使用 toType函数一样。如果只改变了默认表达式,该语句几乎不会做任何复杂操作,并且几乎是立即执行完成的。
示例:
ALTER TABLE visits MODIFY COLUMN browser Array(String)
改变列的类型是唯一的复杂型动作 - 它改变了数据文件的内容。对于大型表,执行起来要花费较长的时间。 该操作分为如下处理步骤:
- 为修改的数据准备新的临时文件
- 重命名原来的文件
- 将新的临时文件改名为原来的数据文件名
- 删除原来的文件
仅仅在第一步是耗费时间的。如果该阶段执行失败,那么数据没有变化。如果执行后续的步骤中失败了,数据可以手动恢复。例外的情形是,当原来的文件从文件系统中被删除了,但是新的数据没有写入到临时文件中并且丢失了。
列操作的 ALTER
行为是可以被复制的。这些指令会保存在ZooKeeper中,这样每个副本节点都能执行它们。所有的 ALTER
将按相同的顺序执行。 The query waits for the appropriate actions to be completed on the other replicas. 然而,改变可复制表的列是可以被中断的,并且所有动作都以异步方式执行。
https://clickhouse.com/docs/zh/sql-reference/statements/alter/