You need to enable JavaScript to run this app.
文档中心
ByteHouse 企业版

ByteHouse 企业版

复制全文
下载 pdf
DDL
修改语句 (ALTER)
复制全文
下载 pdf
修改语句 (ALTER)

ALTER TABLE 语句可用于修改列、分区,也可用于执行更新数据、删除数据、添加表约束、变更表设置、调整索引、更改 TTL 等操作。

列操作(COLUMN)

添加列(ADD COLUMN)

在现有表中新增列,支持指定名称、类型、编码和默认表达式。

语法

ALTER TABLE [tableIdentifier]
ADD COLUMN [IF NOT EXISTS] [tableColumnDfnt]
[AFTER name_after];

参数说明

参数

是否必填

作用

tableIdentifier

是

目标表名称(格式:[db_name.]table_name)

IF NOT EXISTS

否

添加 IF NOT EXISTS 子句,则如果列已经存在,查询不会返回错误。

tableColumnDfnt

是

列定义:column_name data_type [CODEC(codec_name)] [DEFAULT expr]

AFTER name_after

否

指定了列 AFTER name_after,则将新列将添加在指定列之后。

FIRST

否

使用 FIRST 子句可将列添加到表的开头。

注意

  • 如果未指定 AFTER name_after 或 FIRST,新列将被添加到表的末尾。
  • 同语句多列操作时,AFTER 可引用本语句已添加列。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 添加列
ALTER TABLE sample_db.sample_table 
ADD COLUMN IF NOT EXISTS column_name String 
  COMMENT 'column comment here' 
AFTER order_by_column;

修改列(MODIFY COLUMN)

MODIFY COLUMN 语句可用于调整表中列的属性(如类型、默认值、编码等)。

语法

ALTER TABLE [tableIdentifier] MODIFY COLUMN [IF EXISTS] [tableColumnDfnt]

对于不同类型的列,可执行的操作如下:

  • 排序列(Order by column):可以修改其 default_expr、注释(comment)、编码方式(codec)。
  • 分区列(Partition by column):可以修改其注释(comment)。
  • 普通列(Normal column):可以修改其类型(type)、default_expr、注释(comment)、编码方式(codec)。

参数说明

参数

是否必填

作用

IF EXISTS

否

仅当列存在时执行操作(避免无效列报错)

tableColumnDfnt

是

添加新列定义,示例:column_name [NEW_TYPE] [CODEC(...)] [DEFAULT ...] [COMMENT ...]

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String,
    `normal_column` Int64 DEFAULT 0
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 修改列 normal_column,并更新其数据类型、注释及默认值
ALTER TABLE sample_db.sample_table
MODIFY COLUMN IF EXISTS normal_column String 
DEFAULT 'new_default_value' 
COMMENT 'new comment';

移除表属性(MODIFY COLUMN REMOVE)

移除表的属性,包括DEFAULT, ALIAS, MATERIALIZED, CODEC, COMMENT, TTL, SETTINGS。

语法

ALTER TABLE table_name MODIFY COLUMN column_name REMOVE property; 

示例:Remove DEFAULT

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String,
    `normal_column` Int64 DEFAULT 0
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 移除 DEFAULT 属性
ALTER TABLE sample_db.sample_table
MODIFY COLUMN normal_column
REMOVE DEFAULT;

修改表参数配置(MODIFY SETTING)

修改表的参数设置。

语法

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

示例

修改字段 max_compress_block_size 到 1MB:

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String,
    `normal_column` Int64 DEFAULT 0
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 修改字段 max_compress_block_size 到 1MB
ALTER TABLE sample_db.sample_table 
MODIFY SETTING max_compress_block_size = 1048576; 

重置表参数设置(RESET SETTING)

重置表参数设置,同时移除表 CREATE 语句列表达式的参数设置声明。

语法

ALTER TABLE table_name RESET SETTING name,...; 

示例

重设置表参数 max_compress_block_size 为 default 值:

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String,
    `normal_column` Int64 DEFAULT 0
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 重设置表参数 max_compress_block_size 为 default 值
ALTER TABLE sample_db.sample_table 
RESET SETTING max_compress_block_size; 

删除列(DROP COLUMN)

删除表中的一列。分区列(Partition by columns)和排序列(order by columns)不允许删除。

语法

ALTER TABLE [tableIdentifier] DROP COLUMN [IF EXISTS] column_name; 

参数说明

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

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String,
    `normal_column` Int64
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 删除列 normal_column
ALTER TABLE sample_db.sample_table DROP COLUMN IF EXISTS normal_column;

重命名列(RENAME COLUMN)

重命名表中的列。使用时请注意:

  • 不能将新列名重命名为已存在的列名。
  • 不能将列重命名为自身。
  • 重命名的原始列必须存在。

语法

ALTER TABLE [tableIdentifier] RENAME COLUMN [IF EXISTS] column_name_from TO column_name_to; 

参数说明

参数

是否必填

说明

column_name_from

是

原列名(需存在于表中)。

column_name_to

是

新列名(需唯一且不同于原列名)。

IF EXISTS

否

若原列不存在则跳过操作,避免报错。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column ` String,
    `normal_column` Int64
)
ENGINE = `MergeTree`
ORDER BY (`order_by_column`);

-- 3. 重命名列
ALTER TABLE sample_db.sample_table 
RENAME COLUMN IF EXISTS column_name TO new_column_name

清除列(CLEAR COLUMN)

清空指定分区中某列的所有数据。

语法

ALTER TABLE table_name CLEAR COLUMN [IF EXISTS] name IN PARTITION partition_name

示例

ALTER TABLE sample_db.sample_table CLEAR COLUMN browser IN PARTITION tuple()

注释列(COMMENT COLUMN)

为列添加注释。

语法

ALTER TABLE table_name COMMENT COLUMN [IF EXISTS] name 'Text comment'

示例

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

分区操作(PARTITION)

分离分区|数据块(DETACH PARTITION|PART)

将表中指定分区或数据 part 的数据移至分离目录。分离后,服务器不再识别该分区,但您可使用 ATTACH 语句重新关联。
执行分离操作后,您可以对分离目录中的数据执行任何操作,支持将其从文件系统中删除,或仅将其保留。

语法

ALTER TABLE table_name DETACH PARTITION|PART partition_expr 

示例 1:分离分区

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2019-01-01', 'firefox', 9, 20, 2);

-- 4. 分离分区
ALTER TABLE sample_db.sample_table DETACH PARTITION '2020-11-21';

示例 2:分离数据块

-- 1. 创建数据库(若不存在)
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.detachPart ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.detachPart ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column  
ORDER BY (`order_by_column`); 

-- 3. 插入测试数据(生成多个数据块)
INSERT INTO sample_db.detachPart
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),  
('order2', '2019-01-01', 'firefox', 9, 20, 2), 
('order3', '2020-11-21', 'safari', 10, 30, 3); 

-- 4. 查询数据块信息(获取需要分离的 Part 名称)
SELECT 
  name,
  partition,         
  rows               
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'detachPart' 
  AND active = 1; 

-- 5. 分离指定数据块(DETACH PART)
-- 使用步骤 4 中获取的 part_name,例如分离 '20201121_1_1_0'
ALTER TABLE sample_db.detachPart
DETACH PART '20201121_1_1_0';  

-- 6. 验证数据块是否已分离
SELECT 
  name,
  partition,         
  rows               
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'detachPart'; 

删除分区|数据块(DROP PARTITION|PART)

从表中删除指定的分区或数据 part。执行后,系统会将该分区标记为非活动状态,并在大约 10 分钟内完全删除数据。

语法

ALTER TABLE table_name  DROP PARTITION|PART partition_expr 

示例 1:删除分区

支持所有表,底层直接删除目录,性能好,建议优先使用。

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2019-01-01', 'firefox', 9, 20, 2);

-- 4. 删除分区
ALTER TABLE sample_db.sample_table DROP PARTITION '2020-11-21';

示例 2:根据条件删除分区

您可以使用 where 子句指定条件,系统将根据您设置的条件筛选并删除分区。其中,toDate(toStartOfDay(date1))是 PARTITION BY 后的语法参数。

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 根据条件删除分区
ALTER TABLE sample_db.sample_table
DROP PARTITION WHERE toDate(partition_column) > '2024-10-06';

示例 3:删除数据块

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2019-01-01', 'firefox', 9, 20, 2);

-- 4. 查询数据块信息(获取需要分离的 Part 名称)
SELECT 
  name,
  partition,         
  rows               
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'samppe_table' 
  AND active = 1; 

-- 5. 删除 Part 
-- 使用步骤 4 中获取的 part_name,例如分离 '20201121_1_1_0'
ALTER TABLE sample_db.sample_table DROP PART '20201121_1_1_0';

从 detached 目录删除分区|数据块(DROP DETACHED PARTITION|PART)

从 detached 目录中移除指定的 part 或指定分区的所有 part。

语法

ALTER TABLE table_name DROP DETACHED PARTITION|PART partition_expr

示例 1:从 detached 目录删除分区

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 从 detached 目录删除分区
ALTER TABLE sample_db.sample_table DROP DETACHED PARTITION '2020-10-05'
SETTINGS allow_drop_detached = 1;

示例 2:从 detached 目录删除数据块

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 查询数据块信息(获取需要分离的 Part 名称)
SELECT 
  name,
  partition,         
  rows               
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'samppe_table' 
  AND active = 1; 

-- 5. 从 detached 目录删除 Part 
-- 使用步骤 4 中获取的 part_name,例如分离 '20201121_1_1_0'
ALTER TABLE sample_db.sample_table DROP DETACHED PART '20201121_1_1_0'
SETTINGS allow_drop_detached = 1;

从 detached 目录恢复分区|数据块**(​**ATTACH PARTITION|PART)

将已分离至detached目录的分区数据重新添加到表中,支持为整个分区或单独的分区添加数据。恢复关联后,可重新查询和访问分区。

语法

ALTER TABLE table_name  ATTACH PARTITION|PART partition_expr 

示例 1:从 detached 目录恢复分区

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 从 detached 目录删除分区
ALTER TABLE sample_db.sample_table DROP DETACHED PARTITION '2020-10-05';

-- 5. 从 detached 目录恢复分区
ALTER TABLE sample_db.sample_table ATTACH PARTITION '2020-10-05'; 

示例 2:从 detached 目录恢复数据块

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 查询数据块信息(获取需要分离的 Part 名称)
SELECT 
  name,
  partition,         
  rows               
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'samppe_table' 
  AND active = 1; 
 
-- 5. 从 detached 目录删除 Part 
-- 使用步骤 4 中获取的 part_name,例如分离 '20201121_1_1_0'
ALTER TABLE sample_db.sample_table DROP DETACHED PART '20201121_1_1_0';

-- 6. 从 detached 目录恢复 Part 
ALTER TABLE sample_db.sample_table ATTACH PART '20201121_1_1_0'; 

ATTACH PARTITION FROM

将源表(table1)的指定分区数据复制到目标表(table2),并注册为目标表的分区。

语法

ALTER TABLE table2 ATTACH PARTITION partition_expr FROM table1 

注意:

  • 数据不会从 table1 或 table2 中删除。
  • table1 可以是一个临时表。

执行前,请确保您指定的表满足以下条件:

  • 两个表必须具有相同的结构。
  • 两个表必须具有相同的分区键、排序键和主键。
  • 两个表必须具有相同的索引和投影。
  • 两个表必须具有相同的存储策略。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
DROP TABLE IF EXISTS sample_db.sample_table2 ON CLUSTER sample_cluster;

-- 3. 创建表 1
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 4. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 5. 创建表 2
CREATE TABLE IF NOT EXISTS sample_db.sample_table2 ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 6. 将源表(sample_db.sample_table)的指定分区数据复制到目标表(sample_db.sample_table2)
ALTER TABLE sample_db.sample_table2
ATTACH PARTITION '2020-10-05' 
FROM sample_db.sample_table;

替换分区(REPLACE PARTITION)

将源表(table1)的指定分区数据覆盖到目标表(table2)的同名分区,支持原子性替换,确保数据一致性。

语法

ALTER TABLE table2 REPLACE PARTITION partition_expr FROM table1 

注意:

  • 源表(table1)的数据不会被删除。
  • 源表(table1)可以是临时表。

执行前,请确保您指定的表满足以下条件:

  • 两张表必须具有相同的结构。
  • 两张表必须具有相同的分区键、排序键和主键。
  • 两张表必须具有相同的索引和投影。
  • 两张表必须具有相同的存储策略。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
DROP TABLE IF EXISTS sample_db.sample_table2 ON CLUSTER sample_cluster;

-- 3. 创建表 1
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 4. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 5. 创建表 2
CREATE TABLE IF NOT EXISTS sample_db.sample_table2 ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 6. 将源表(sample_db.sample_table)的指定分区数据覆盖到目标表(sample_db.sample_table2)的同名分区
ALTER TABLE sample_db.sample_table2
REPLACE PARTITION '2020-10-05' 
FROM sample_db.sample_table;

跨表移动分区数据(​MOVE PARTITION TO TABLE)

将源表(table_source)的指定分区数据迁移至目标表(table_dest),并从源表中删除该分区。

语法

ALTER TABLE table_source MOVE PARTITION partition_expr TO TABLE table_dest 

执行前,请确保您指定的表满足以下条件:

  • 两张表必须具有相同的结构。
  • 两张表必须具有相同的分区键、排序键和主键。
  • 两张表必须具有相同的索引和投影。
  • 两张表必须具有相同的存储策略。
  • 两张表必须属于相同的引擎家族(如均为MergeTree或均为ReplicatedMergeTree)。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table_source ON CLUSTER sample_cluster;
DROP TABLE IF EXISTS sample_db.sample_table_dest ON CLUSTER sample_cluster;

-- 3. 创建表 1
CREATE TABLE IF NOT EXISTS sample_db.sample_table_source ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 4. 插入数据
INSERT INTO sample_db.sample_table_source
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 5. 创建表 2
CREATE TABLE IF NOT EXISTS sample_db.sample_table_dest ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 6. 将源表(sample_db.sample_table_source)的指定分区数据迁移至目标表(sample_db.sample_table_dest),并从源表中删除该分区
ALTER TABLE sample_db.sample_table_source
MOVE PARTITION '2020-10-05' 
TO TABLE sample_db.sample_table_dest;

-- 7. 验证目标表接收了分区数据
SELECT 
    partition_column AS partition,
    COUNT(*) AS rows,
    any(browser) AS browser_example, 
    any(hour) AS hour_example     
FROM sample_db.sample_table_dest
GROUP BY partition_column;

-- 8. 验证源表分区已删除
SELECT 
    partition_column AS partition,
    COUNT(*) AS rows
FROM sample_db.sample_table_source
GROUP BY partition_column;

重置分区内列值(​CLEAR COLUMN IN PARTITION)

重置分区中指定列的所有值。如果在创建表时确定了 DEFAULT 子句,此查询会将列值设置为指定的默认值。

语法

ALTER TABLE table_name CLEAR COLUMN column_name IN PARTITION partition_expr 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;

-- 3. 创建表
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32 DEFAULT 0,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 4. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 5. 重置分区内列值
ALTER TABLE sample_db.sample_table CLEAR COLUMN hour in PARTITION '2020-10-05';

-- 6. 验证 hour 列的值是否被重置
SELECT *
FROM sample_db.sample_table
WHERE `partition_column` = '2020-10-05';

重置分区内二级索引(​CLEAR INDEX IN PARTITION)

重置分区中指定的二级索引。CLEAR INDEX IN PARTITION 语句与 CLEAR COLUMN 类似,但 CLEAR INDEX IN PARTITION 语句重置的是索引,而不是列数据。

语法

ALTER TABLE table_name CLEAR INDEX index_name IN PARTITION partition_expr 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE sample_db.sample_table ON CLUSTER CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32,
    INDEX idx_browser (`browser`) TYPE minmax GRANULARITY 32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 重置分区内二级索引
ALTER TABLE sample_db.sample_table 
CLEAR INDEX idx_browser 
IN PARTITION '2020-10-05';

创建分区备份(​FREEZE PARTITION)

创建指定分区的本地备份。如果省略 PARTITION 子句,执行该语句将会一次性创建所有分区的备份。

语法

ALTER TABLE table_name FREEZE [PARTITION partition_expr] [WITH NAME 'backup_name'] 

参数说明

参数

是否必填

说明

PARTITION

否

指定需备份的分区表达式。若省略,则备份全量分区。

WITH NAME

否

指定备份集名称(用于标识)。若省略,系统自动生成时间戳名称。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 创建指定分区的本地备份
ALTER TABLE sample_db.sample_table 
FREEZE PARTITION '2020-11-02' 
WITH NAME 'backup_20201102';

移除分区备份(​UNFREEZE PARTITION)

移除磁盘上具有指定名称的 frozen 分区。如果省略 PARTITION 子句,查询将一次性移除所有分区的备份。

语法

ALTER TABLE table_name UNFREEZE [PARTITION 'part_expr'] WITH NAME 'backup_name' 

参数说明

参数

是否必填

说明

PARTITION

否

指定需删除备份的分区表达式。若省略,则删除备份集中的所有分区。

WITH NAME

否

指定备份集名称(对应 FREEZE 时使用的名称)。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 创建指定分区的本地备份
ALTER TABLE sample_db.sample_table 
FREEZE PARTITION '2020-11-02' 
WITH NAME 'backup_20201102';

-- 5. 移除分区备份
ALTER TABLE sample_db.sample_table 
UNFREEZE PARTITION '2020-11-02' 
WITH NAME 'backup_20201102';

跨节点同步分区数据(​FETCH PARTITION|PART)

该子句用于在同一分片的不同副本间同步分区或数据块(Part),适用于数据修复、副本数据补齐等场景。

注意

  • 该同步操作仅适用于 HaMergeTree 类型的表,更多 HaMergeTree 的说明请参见HaMergeTree。
  • 使用前,请确保您使用的集群为多副本集群。

语法

ALTER TABLE [db.]table_name FETCH PARTITION|PART partition_expr FROM '{another_replica_name}'

参数说明

参数

是否必填

说明

FROM another_replica_name

是

指定数据来源的副本,配置为 HaMergeTree 副本的 IP 地址。可通过以下命令查询:

SELECT replica_name, replica_path
FROM system.ha_replicas
WHERE database = 'sample_db' AND table = 'fetchPart_local';

示例

-- 1. 创建表
-- 本地表(local table)
CREATE TABLE IF NOT EXISTS sample_db.fetchPart_local (
  `id` Int16,
  `name` String
) 
ENGINE = HaMergeTree(
    '/clickhouse/2100957468/sample_cluster/sample_db.fetchPart_local/{shard}',
    '{replica}'
)
PARTITION BY id
ORDER BY id
SETTINGS
  storage_policy = 's3_cold', -- 使用该设置前,请确保您所在的集群已开启冷热存储服务
  index_granularity = 8192;

-- 分布式表(distributed table)
CREATE TABLE IF NOT EXISTS sample_db.fetchPart
AS sample_db.fetchPart_local 
Engine = Distributed (
    sample_cluster,
    `sample_db`,
    `fetchPart_local`,
    intHash64(id)
  );

-- 2. 插入测试数据
INSERT INTO sample_db.fetchPart (id, name) VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Eve');

-- 3. 查询分区、数据块信息,用于获取同步所需的信息
-- 3.1. 查询分区 ID
SELECT DISTINCT partition_id 
FROM system.parts 
WHERE database = 'sample_db' AND table = 'fetchPart_local' AND active=1;

-- 3.2 查询分区 1 下所有 part
SELECT name 
FROM system.parts 
WHERE database = 'sample_db' AND table = 'fetchPart_local' AND partition='1' AND active;

-- 3.3 查询副本名和副本路径
SELECT replica_name, replica_path 
FROM system.ha_replicas 
WHERE database = 'sample_db' AND table = 'fetchPart_local';

-- 4. FETCH 操作示例
-- 4.1 使用分区 ID 同步整个分区
-- 场景:副本 1(192.xxx.xx.27)缺失分区 1 的数据,从同分片的副本 2(192.xxx.xx.26)同步
ALTER TABLE sample_db.fetchPart_local 
FETCH PARTITION ID '1' 
FROM '192.xxx.xx.26';

-- 4.2 使用 Part 名称同步单个 part
-- 场景:副本 1 的分区 1 中,数据块 '1_0_0_0' 损坏,从副本 2 同步该数据块
ALTER TABLE sample_db.fetchPart_local 
FETCH PART '1_0_0_0' 
FROM '192.xxx.xx.26';

跨磁盘迁移分区数据(​MOVE PARTITION|PART)

将指定分区从当前磁盘迁移至其他磁盘或卷组。

注意

使用前,请确保您使用的集群已开启冷热存储,操作详情请参见冷热分层存储。

语法

ALTER TABLE table_name MOVE PARTITION|PART partition_expr TO DISK|VOLUME 'disk_or_volume_name' 

参数说明

参数

是否必填

说明

DISK/VOLUME

是

目标存储位置类型:

  • DISK:指定具体磁盘名称。
  • VOLUME:指定卷组。

disk_or_volume_name

是

磁盘名或卷组名。

示例

-- 1. 创建支持多存储策略的表
CREATE TABLE IF NOT EXISTS sample_db.order_records (
  `order_id` Int64,
  `order_date` Date,
  `amount` Float64,
  `status` String
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(order_date) 
ORDER BY (order_id, order_date)
SETTINGS 
  storage_policy = 's3_cold';  -- 关联存储策略名称

-- 2. 插入测试数据
-- 2023年12月数据(假设为冷数据)
INSERT INTO sample_db.order_records 
VALUES 
  (1001, '2023-12-05', 199.99, 'completed'),
  (1002, '2023-12-15', 299.50, 'completed');

-- 2024年1月数据(假设为热数据)
INSERT INTO sample_db.order_records 
VALUES 
  (2001, '2024-01-02', 399.00, 'pending'),
  (2002, '2024-01-10', 499.99, 'completed');

-- 3. 查看分区和数据块的存储位置(移动前确认)
-- 查看所有分区的存储信息
SELECT 
  partition,  
  name,  
  disk_name  
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'order_records' 
  AND active = 1; 

-- 4. MOVE 操作示例
-- 4.1 移动整个分区到指定磁盘(DISK)
-- 场景:将2023年12月的冷数据从"default"迁移到"s3"
ALTER TABLE sample_db.order_records
MOVE PARTITION '202312'  -- 分区表达式(与PARTITION BY定义匹配)
TO DISK 's3';     -- 目标磁盘名称(需在storage_policy中存在)

-- 4.2 移动单个数据块(PART)到指定卷(VOLUME)
-- 场景:将2024年1月的某个数据块从"default"迁移到"s3"
-- 注意:需先通过步骤3获取具体的part_name(如202401_1_1_0)
ALTER TABLE sample.order_records
MOVE PART '202401_2_2_0'  -- 数据块名称(从system.parts查询获取)
TO VOLUME 's3';  -- 目标卷名称(卷是磁盘的逻辑组合)

-- 5. 验证移动结果
-- 5.1 验证分区移动至磁盘
SELECT 
  partition,
  disk_name
FROM system.parts 
WHERE 
  database = 'sample_db' 
  AND table = 'order_records' 
  AND active = 1;
  
-- 5.2 验证 part 移动至指定卷
SELECT path
FROM system.parts 
WHERE name = '202401_2_2_0' AND table = 'order_records';

分区内条件更新(​UPDATE IN PARTITION)

在指定分区内按条件批量更新数据。

语法

ALTER TABLE [db.]table
    UPDATE 
        column1 = expr1,
        column2 = expr2,  
        ...
    [IN PARTITION partition_expr]  -- 可选:指定分区
    WHERE filter_expr;            -- 过滤条件

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 3. 插入数据
INSERT INTO sample_db.sample_table
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 方式一:使用分区名称更新
ALTER TABLE sample_db.sample_table UPDATE x = x + 1 IN PARTITION '2020-11-02' WHERE p = 2;

-- 方式二:使用分区 ID
-- 查询分区 ID
SELECT DISTINCT
    partition_id
FROM system.parts
WHERE database = 'sample_db' AND table = 'sample_table' AND active = 1;

-- 使用分区 ID 更新
ALTER TABLE sample_db.sample_table UPDATE x = x + 1 IN PARTITION ID '20201005' WHERE p = 2; 

分区内条件删除(DELETE IN PARTITION)

在指定分区内按条件删除数据行。

注意

  • 对于 HaMergeTree 表,delete where 只能在本地(local)表上操作,不支持在分布式表操作。
  • 仅 ByteHouse 企业版 v2.4 及以上版本支持 delete where 语法。

语法

ALTER TABLE [db.]table DELETE [IN PARTITION partition_expr] WHERE filter_expr 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table_local ON CLUSTER sample_cluster;
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table_local ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
) ENGINE = HaMergeTree('/clickhouse/tables/{shard}/{database}/local_table_name', '{replica}')
PARTITION BY partition_column
ORDER BY (`order_by_column`);

CREATE TABLE sample_db.sample_table
    AS sample_db.sample_table_local
    ENGINE = Distributed(sample_cluster, sample_db, sample_table_local, hour);

-- 3. 插入数据
INSERT INTO sample_db.sample_table_local ON CLUSTER sample_cluster
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 使用分区名称删除
ALTER TABLE sample_db.sample_table_local ON CLUSTER sample_cluster DELETE IN PARTITION '2020-11-02' WHERE p = 2; 

-- 使用分区 ID 删除
ALTER TABLE sample_db.sample_table_local ON CLUSTER sample_cluster DELETE IN PARTITION ID '2' WHERE p = 2;

更新操作(UPDATE)

您可以使用此基本查询格式更新数据。

注意事项

  1. filter_expr 必须是 UInt8 类型。该查询将指定列的值更新为行中相应表达式的值,对于这些行,filter_expr取值为非零。使用CAST操作符将数值映射到列的类型上。不支持更新用于计算主键或分区键的列。
  2. 单查询语句支持使用逗号分隔多条命令。
  3. 此语句的查询处理默认是异步操作。

语法

ALTER TABLE 的前缀使这个语法与其他大多数支持 SQL 的系统不同。它的目的是表明,与 OLTP 数据库中的类似查询不同,这是一个繁重的操作,不是为频繁使用而设计。

ALTER TABLE [db.]table
    UPDATE 
        column1 = expr1,
        column2 = expr2, 
        ...
    [IN PARTITION partition_id]  -- 可选分区
    WHERE filter_expr;          -- 过滤条件

参数说明

IN PARTITION partition_id:可选,如果表数据量较大,或者表的 part 数量较多,建议添加该条件,分区级别执行 update 操作,更快、更稳定。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table_local ON CLUSTER sample_cluster;
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table_local ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
) ENGINE = HaMergeTree('/clickhouse/tables/{shard}/{database}/local_table_name', '{replica}')
PARTITION BY partition_column
ORDER BY (`order_by_column`);

CREATE TABLE sample_db.sample_table
    AS sample_db.sample_table_local
    ENGINE = Distributed(sample_cluster, sample_db, sample_table_local, hour);

-- 3. 插入数据
INSERT INTO sample_db.sample_table_local ON CLUSTER sample_cluster
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 更新数据
ALTER TABLE sample_db.sample_table_local ON CLUSTER sample_cluster 
    UPDATE browser = 'edge' 
    WHERE order_by_column = 'order1';

删除操作(DELETE)

从表中删除数据。

注意

  • 对于 HaMergeTree 表,delete where 只能在本地(local)表上操作,不支持在分布式表操作。
  • 仅 ByteHouse 企业版 v2.4 及以上版本支持 delete where 语法。

语法

ALTER TABLE [tableIdentifier] DELETE [IN PARTITION partition_id] WHERE filter_expr;

参数说明

IN PARTITION partition_id:可选,如果表数据量较大,或者表的 part 数量较多,建议添加该条件,分区级别执行 delete 操作,更快、更稳定。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table_local ON CLUSTER sample_cluster;
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table_local ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
) ENGINE = HaMergeTree('/clickhouse/tables/{shard}/{database}/local_table_name', '{replica}')
PARTITION BY partition_column
ORDER BY (`order_by_column`);

CREATE TABLE sample_db.sample_table
    AS sample_db.sample_table_local
    ENGINE = Distributed(sample_cluster, sample_db, sample_table_local, hour);

-- 3. 插入数据
INSERT INTO sample_db.sample_table_local ON CLUSTER sample_cluster
VALUES
('order1', '2020-11-21', 'chrome', 8, 10, 2),
('order2', '2020-11-02', 'chrome', 8, 10, 2),
('order3', '2020-10-05', 'firefox', 9, 20, 2);

-- 4. 删除数据
ALTER TABLE sample_db.sample_table_local ON CLUSTER sample_cluster 
    DELETE WHERE browser = 'firefox';

FAST DELETE

FAST DELETE 通过 mutation 运行,但属于轻量化 Mutation 操作。其底层执行逻辑为:FAST DELETE 通过对原 part 数据文件进行 HardLink,同时生成一个 Bitmap 小文件,用于记录被标记删除的数据行号,该过程执行比较轻量,适合希望快速删除部分数据或需要大量删除数据时使用。当前该功能仅支持 HaUniqueMergeTree 和 HaMergeTree 表引擎。
FAST DELETE 语句与 DELETE 语句的差异说明如下:

语法

删除方式

执行方式

执行代价

Delete Where

物理删除

异步Mutation

较重、代价大

Fastdelete Where

标记删除

异步Mutation

轻量、代价较小

语法

ALTER TABLE db.table FASTDELETE [col_name [, ...]] 
[IN PARTITION {(ID partition_id) | (partition_name)}] 
WHERE filter_expr

参数

是否必填

配置说明

db.table

是

指定目标数据对象。

  • db:指定数据库。
  • table:指定为本地(local)表。

col_name

否

指定需删除的列名。如需指定多列,请使用逗号(,)分隔。

IN PARTITION

否

指定删除操作的目标分区,支持指定分区 ID 或分区名称。
如果表数据量较大,或者表的 part 数量较多,建议添加该条件,分区级别执行 delete 操作,更快、更稳定。

WHERE

是

指定数据筛选条件表达式,仅删除满足该条件的数据。

示例

-- 1. 创建测试表
DROP TABLE IF EXISTS test.test_fd;

-- 创建本地表
CREATE TABLE test.test_fd
(
    `p_date` Date,
    `id` Int32,
    `age` Int32,
    `event` String,
    `ab` Array(Int32)
)
ENGINE = HaUniqueMergeTree(concat('/clickhouse/tables/', currentDatabase(), '/test_fd'), '1')
PARTITION BY p_date
ORDER BY id
UNIQUE KEY id
SETTINGS index_granularity = 8192;

-- 创建分布式表
CREATE TABLE test.test_fd_dis on cluster your_cluster_name
(
    `p_date` Date,
    `id` Int32,
    `age` Int32,
    `event` String,
    `ab` Array(Int32)
)
ENGINE = Distributed('your_cluster_name', 'test', 'test_fd_cluster_local', id);

-- 2. 插入数据
INSERT INTO test.test_fd VALUES ('2021-01-01', 1, 18, 'a', [1,2,3]),('2021-01-01', 2, 18, 'b', [1,2,3]),('2021-01-01', 3, 18, 'c', [1,2,3]),('2021-01-02', 2, 21, 'a', [1,2,3]),('2021-01-02', 3, 22, 'b', [1,2,3]),('2021-01-03', 3, 23, 'c', [1,2,3]);

-- 3. 删除数据
ALTER TABLE test.test_fd ON CLUSTER your_cluster_name FASTDELETE WHERE p_date = '2021-01-01' and id > 1;

约束操作(CONSTRAINT)

添加约束(ADD CONSTRAINT)

为表添加约束。

语法

ALTER TABLE [tableIdentifier] 
    ADD CONSTRAINT [IF NOT EXISTS] constraint_name 
    CHECK columnExpr; 

参数说明

参数

是否必填

说明

IF NOT EXISTS

否

可选参数,确保约束不存在时不报错。

constraint_name

是

约束名称,必须唯一。

CHECK columnExpr

是

定义约束规则。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

--  3. 添加约束 check_str
ALTER TABLE sample_db.sample_table
    ADD CONSTRAINT IF NOT EXISTS check_str 
    CHECK order_by_column != 'forbidden_string'

删除约束(DROP CONSTRAINT)

删除指定表中的约束。

语法

ALTER TABLE [tableIdentifier] DROP CONSTRAINT [IF EXISTS] constraint_name; 

指定了IF EXISTS子句,如果约束不存在,查询将不会返回错误。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;

-- 3. 创建包含了 check_str 约束的表
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `order_by_column` String,
    `partition_column` Date,
    `browser` String,
    `hour` Int32,
    `x` Int32,
    `p` Int32,
    CONSTRAINT check_str CHECK (`order_by_column` != 'forbidden_string')
)
ENGINE = MergeTree
PARTITION BY partition_column
ORDER BY (`order_by_column`);

-- 4. 删除约束 check_str
ALTER TABLE sample_db.sample_table DROP CONSTRAINT IF EXISTS check_str

表设置操作(SETTINGS)

这是一组更改表设置的操作。您可以修改表设置或将其重置为默认值,支持单个查询中同时更改多个设置。 如果指定名称的设置不存在,则查询会引发异常。

语法

ALTER TABLE [db].name MODIFY|RESET SETTING ... 

修改设置

更改表设置。

语法

MODIFY SETTING setting_name=value [, ...] 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `id` UInt32,
    `data` String,
    `partition_col` Date  -- 新增分区列
)
ENGINE = MergeTree
PARTITION BY partition_col  -- 显式指定分区键(分区表达式字段数量为 1)
ORDER BY id;

-- 3. 修改表的参数值
ALTER TABLE sample_db.sample_table
    MODIFY SETTING 
        max_part_loading_threads = 8,
        max_parts_in_total = 50000;

重置设置

重置表设置为默认值。如果设置处于默认状态,则系统将不采取任何操作。

语法

RESET SETTING setting_name [, ...] 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;

-- 3. 创建表,并将 max_part_loading_threads 参数设置为 8
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `id` UInt32,
    `data` String,
    `partition_col` Date  
)
ENGINE = MergeTree
PARTITION BY partition_col  
ORDER BY id
SETTINGS max_part_loading_threads=8;

-- 4. 重置 max_part_loading_threads 参数为默认值
ALTER TABLE sample_db.sample_table
    RESET SETTING max_part_loading_threads;

索引操作(INDEX)

ByteHouse 支持使用以下操作,其中,前两个命令是轻量级的,仅更改元数据或删除文件。

语法

  • 向表元数据添加索引描述

    ALTER TABLE [db.]name
        ADD INDEX index_name expression
        TYPE index_type
        GRANULARITY value
        [FIRST | AFTER column_name];
    
  • 从表元数据中删除索引描述并从磁盘中删除索引文件

    ALTER TABLE [db].name DROP INDEX name
    
  • 在分区 partition_name 中重建二级索引名称

    ALTER TABLE [db.]table MATERIALIZE INDEX name IN PARTITION partition_name 
    

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 创建测试表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `id` UInt32,
    `data` String,
    `partition_col` Date,
    INDEX idx_data (`data`) TYPE bloom_filter GRANULARITY 4
)
ENGINE = MergeTree
PARTITION BY partition_col
ORDER BY id;

-- 3. 插入测试数据
INSERT INTO sample_db.sample_table
VALUES 
(1, 'data_20240101', '2024-01-01'),
(2, 'data_20240102', '2024-01-02'),
(3, 'data_20240101', '2024-01-01');

-- 4. 删除索引
ALTER TABLE sample_db.sample_table 
DROP INDEX IF EXISTS idx_data;

-- 5. 添加索引
ALTER TABLE sample_db.sample_table 
ADD INDEX IF NOT EXISTS idx_data_new data 
TYPE bloom_filter 
GRANULARITY 4;

-- 6. 在分区中重建二级索引
ALTER TABLE sample_db.sample_table MATERIALIZE INDEX idx_data_new IN PARTITION '2024-01-01';

TTL 操作(TTL)

修改 TTL(MODIFY TTL)

更改表 TTL。TTL 子句必须使用按列分区中的字段。

语法

ALTER TABLE [tableIdentifier] [IF EXISTS] MODIFY [ttlClause];

参数

说明

[IF EXISTS]

可选参数,确保表不存在时不报错(建议生产环境使用)。

MODIFY [ttlClause]

TTL 表达式,必须基于分区字段(如 date + INTERVAL 30 DAY)。

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;

-- 3. 创建 TTL 为 1 天的表
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `d` DateTime
)
ENGINE = `MergeTree`
PARTITION BY d
ORDER BY `d`
TTL d + INTERVAL 1 DAY

-- 4. 修改 TTL 为 2 个月
ALTER TABLE sample_db.sample_table
MODIFY TTL d + INTERVAL 2 MONTH;

移除TTL(REMOVE TTL)

移除表的 TTL。

语法

ALTER TABLE [tableIdentifier] REMOVE TTL; 

示例

-- 1. 创建库
CREATE DATABASE IF NOT EXISTS sample_db ON CLUSTER sample_cluster;

-- 2. 删除现存表
DROP TABLE IF EXISTS sample_db.sample_table ON CLUSTER sample_cluster;

-- 3. 创建 TTL 为 1 天的表
CREATE TABLE IF NOT EXISTS sample_db.sample_table ON CLUSTER sample_cluster
(
    `d` DateTime
)
ENGINE = `MergeTree`
PARTITION BY d
ORDER BY d
TTL d + INTERVAL 1 DAY

-- 4. 移除表 TTL
ALTER TABLE sample_db.sample_table
REMOVE TTL
最近更新时间:2025.12.12 10:31:26
这个页面对您有帮助吗?
有用
有用
无用
无用