跳到主要内容
跳到主要内容

列操作

一组允许更改表结构的查询。

语法

ALTER [TEMPORARY] TABLE [db].name [ON CLUSTER cluster] ADD|DROP|RENAME|CLEAR|COMMENT|{MODIFY|ALTER}|MATERIALIZE COLUMN ...

在查询中,指定一个或多个逗号分隔的操作列表。每个操作都是对列的操作。

支持以下操作

ADD COLUMN

ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [codec] [AFTER name_after | FIRST]

向表中添加一个新列,具有指定的 nametypecodecdefault_expr (参见 默认表达式 部分)。

如果包含 IF NOT EXISTS 子句,则当列已存在时,查询不会返回错误。如果您指定 AFTER name_after(另一个列的名称),则该列将添加到表列列表中的指定列之后。如果您想将列添加到表的开头,请使用 FIRST 子句。否则,该列将添加到表的末尾。对于一系列操作,name_after 可以是在先前操作之一中添加的列的名称。

添加列只会更改表结构,而不会对数据执行任何操作。数据在 ALTER 之后不会出现在磁盘上。如果在从表中读取数据时列中缺少数据,则会使用默认值填充(如果存在默认表达式,则执行默认表达式,否则使用零或空字符串)。列在合并数据 parts(参见 MergeTree)后才会出现在磁盘上。

这种方法允许我们立即完成 ALTER 查询,而不会增加旧数据的体积。

示例

ALTER TABLE alter_test ADD COLUMN Added1 UInt32 FIRST;
ALTER TABLE alter_test ADD COLUMN Added2 UInt32 AFTER NestedColumn;
ALTER TABLE alter_test ADD COLUMN Added3 UInt32 AFTER ToDrop;
DESC alter_test FORMAT TSV;
Added1  UInt32
CounterID UInt32
StartDate Date
UserID UInt32
VisitID UInt32
NestedColumn.A Array(UInt8)
NestedColumn.S Array(String)
Added2 UInt32
ToDrop UInt32
Added3 UInt32

DROP COLUMN

DROP COLUMN [IF EXISTS] name

删除名为 name 的列。如果指定了 IF EXISTS 子句,则当列不存在时,查询不会返回错误。

从文件系统中删除数据。由于这会删除整个文件,因此查询几乎立即完成。

提示

如果列被 物化视图 引用,则无法删除该列。否则,它会返回错误。

示例

ALTER TABLE visits DROP COLUMN browser

RENAME COLUMN

RENAME COLUMN [IF EXISTS] name to new_name

将列 name 重命名为 new_name。如果指定了 IF EXISTS 子句,则当列不存在时,查询不会返回错误。由于重命名不涉及底层数据,因此查询几乎立即完成。

注意:在表的键表达式(使用 ORDER BYPRIMARY KEY 指定)中指定的列无法重命名。尝试更改这些列将产生 SQL Error [524]

示例

ALTER TABLE visits RENAME COLUMN webBrowser TO browser

CLEAR COLUMN

CLEAR COLUMN [IF EXISTS] name IN PARTITION partition_name

重置指定分区中列的所有数据。阅读 如何设置分区表达式 部分,了解有关设置分区名称的更多信息。

如果指定了 IF EXISTS 子句,则当列不存在时,查询不会返回错误。

示例

ALTER TABLE visits CLEAR COLUMN browser IN PARTITION tuple()

COMMENT COLUMN

COMMENT COLUMN [IF EXISTS] name 'Text comment'

向列添加注释。如果指定了 IF EXISTS 子句,则当列不存在时,查询不会返回错误。

每个列可以有一个注释。如果列已存在注释,则新注释将覆盖之前的注释。

注释存储在 DESCRIBE TABLE 查询返回的 comment_expression 列中。

示例

ALTER TABLE visits COMMENT COLUMN browser 'This column shows the browser used for accessing the site.'

MODIFY COLUMN

MODIFY COLUMN [IF EXISTS] name [type] [default_expr] [codec] [TTL] [settings] [AFTER name_after | FIRST]
ALTER COLUMN [IF EXISTS] name TYPE [type] [default_expr] [codec] [TTL] [settings] [AFTER name_after | FIRST]

此查询更改 name 列属性

  • 类型

  • 默认表达式

  • 压缩编解码器

  • TTL

  • 列级设置

有关列压缩 CODECS 修改的示例,请参见 列压缩编解码器

有关列 TTL 修改的示例,请参见 列 TTL

有关列级设置修改的示例,请参见 列级设置

如果指定了 IF EXISTS 子句,则当列不存在时,查询不会返回错误。

更改类型时,值会像应用 toType 函数一样进行转换。如果仅更改默认表达式,则查询不会执行任何复杂操作,并且几乎立即完成。

示例

ALTER TABLE visits MODIFY COLUMN browser Array(String)

更改列类型是唯一复杂的操作 – 它会更改包含数据的文件的内容。对于大型表,这可能需要很长时间。

查询还可以使用 FIRST | AFTER 子句更改列的顺序,请参见 ADD COLUMN 描述,但在这种情况下,列类型是强制性的。

示例

CREATE TABLE users (
c1 Int16,
c2 String
) ENGINE = MergeTree
ORDER BY c1;

DESCRIBE users;
┌─name─┬─type───┬
│ c1 │ Int16 │
│ c2 │ String │
└──────┴────────┴

ALTER TABLE users MODIFY COLUMN c2 String FIRST;

DESCRIBE users;
┌─name─┬─type───┬
│ c2 │ String │
│ c1 │ Int16 │
└──────┴────────┴

ALTER TABLE users ALTER COLUMN c2 TYPE String AFTER c1;

DESCRIBE users;
┌─name─┬─type───┬
│ c1 │ Int16 │
│ c2 │ String │
└──────┴────────┴

ALTER 查询是原子性的。对于 MergeTree 表,它也是无锁的。

用于更改列的 ALTER 查询是复制的。指令保存在 ZooKeeper 中,然后每个副本应用它们。所有 ALTER 查询都以相同的顺序运行。查询等待其他副本上完成相应的操作。但是,可以中断更改复制表中的列的查询,所有操作将异步执行。

MODIFY COLUMN REMOVE

删除列属性之一:DEFAULTALIASMATERIALIZEDCODECCOMMENTTTLSETTINGS

语法

ALTER TABLE table_name MODIFY COLUMN column_name REMOVE property;

示例

删除 TTL

ALTER TABLE table_with_ttl MODIFY COLUMN column_ttl REMOVE TTL;

另请参见

MODIFY COLUMN MODIFY SETTING

修改列设置。

语法

ALTER TABLE table_name MODIFY COLUMN column_name MODIFY SETTING name=value,...;

示例

将列的 max_compress_block_size 修改为 1MB

ALTER TABLE table_name MODIFY COLUMN column_name MODIFY SETTING max_compress_block_size = 1048576;

MODIFY COLUMN RESET SETTING

重置列设置,还会删除表的 CREATE 查询的列表达式中的设置声明。

语法

ALTER TABLE table_name MODIFY COLUMN column_name RESET SETTING name,...;

示例

将列设置 max_compress_block_size 重置为其默认值

ALTER TABLE table_name MODIFY COLUMN column_name RESET SETTING max_compress_block_size;

MATERIALIZE COLUMN

物化具有 DEFAULTMATERIALIZED 值表达式的列。当使用 ALTER TABLE table_name ADD COLUMN column_name MATERIALIZED 添加物化列时,不自动填充没有物化值的现有行。MATERIALIZE COLUMN 语句可用于在添加或更新 DEFAULTMATERIALIZED 表达式后重写现有列数据(这仅更新元数据,但不更改现有数据)。请注意,在排序键中物化列是无效操作,因为它可能会破坏排序顺序。实现为 mutation

对于具有新的或更新的 MATERIALIZED 值表达式的列,所有现有行都将被重写。

对于具有新的或更新的 DEFAULT 值表达式的列,行为取决于 ClickHouse 版本

  • 在 ClickHouse < v24.2 中,所有现有行都将被重写。
  • ClickHouse >= v24.2 区分在插入时是否显式指定了具有 DEFAULT 值表达式的列中的行值,或者是否未指定,即从 DEFAULT 值表达式计算得出。如果显式指定了值,则 ClickHouse 会保持原样。如果值是计算出来的,ClickHouse 会将其更改为新的或更新的 MATERIALIZED 值表达式。

语法

ALTER TABLE [db.]table [ON CLUSTER cluster] MATERIALIZE COLUMN col [IN PARTITION partition | IN PARTITION ID 'partition_id'];
  • 如果您指定 PARTITION,则列将仅在指定分区中物化。

示例

DROP TABLE IF EXISTS tmp;
SET mutations_sync = 2;
CREATE TABLE tmp (x Int64) ENGINE = MergeTree() ORDER BY tuple() PARTITION BY tuple();
INSERT INTO tmp SELECT * FROM system.numbers LIMIT 5;
ALTER TABLE tmp ADD COLUMN s String MATERIALIZED toString(x);

ALTER TABLE tmp MATERIALIZE COLUMN s;

SELECT groupArray(x), groupArray(s) FROM (select x,s from tmp order by x);

┌─groupArray(x)─┬─groupArray(s)─────────┐
[0,1,2,3,4]['0','1','2','3','4']
└───────────────┴───────────────────────┘

ALTER TABLE tmp MODIFY COLUMN s String MATERIALIZED toString(round(100/x));

INSERT INTO tmp SELECT * FROM system.numbers LIMIT 5,5;

SELECT groupArray(x), groupArray(s) FROM tmp;

┌─groupArray(x)─────────┬─groupArray(s)──────────────────────────────────┐
[0,1,2,3,4,5,6,7,8,9]['0','1','2','3','4','20','17','14','12','11']
└───────────────────────┴────────────────────────────────────────────────┘

ALTER TABLE tmp MATERIALIZE COLUMN s;

SELECT groupArray(x), groupArray(s) FROM tmp;

┌─groupArray(x)─────────┬─groupArray(s)─────────────────────────────────────────┐
[0,1,2,3,4,5,6,7,8,9]['inf','100','50','33','25','20','17','14','12','11']
└───────────────────────┴───────────────────────────────────────────────────────┘

另请参见

限制

ALTER 查询允许您在嵌套数据结构中创建和删除单独的元素(列),但不能删除整个嵌套数据结构。要添加嵌套数据结构,您可以添加名称类似于 name.nested_name 且类型为 Array(T) 的列。嵌套数据结构等效于多个数组列,这些列的名称在点之前具有相同的前缀。

不支持删除主键或抽样键中的列(在 ENGINE 表达式中使用的列)。仅当更改不会导致数据被修改时,才可能更改主键中包含的列的类型(例如,允许您向 Enum 添加值或将类型从 DateTime 更改为 UInt32)。

如果 ALTER 查询不足以进行您需要的表更改,您可以创建一个新表,使用 INSERT SELECT 查询将数据复制到其中,然后使用 RENAME 查询切换表,并删除旧表。

ALTER 查询会阻止对表的所有读取和写入。换句话说,如果在 ALTER 查询时正在运行长时间的 SELECT,则 ALTER 查询将等待其完成。同时,对此表的全部新查询将在 ALTER 运行时等待。

对于不自行存储数据的表(例如 MergeDistributed),ALTER 仅更改表结构,而不更改从属表的结构。例如,当为 Distributed 表运行 ALTER 时,您还需要为所有远程服务器上的表运行 ALTER