ClickHouse的MergeTree及其家族

本文详细介绍了ClickHouse数据库中的MergeTree系列引擎,包括CREATE TABLE语句的使用,如PartitionBy、OrderBy和PrimaryKey的设置。MergeTree表引擎强制要求OrderBy,用于数据排序。ReplacingMergeTree引擎用于去重,SummingMergeTree引擎则在合并分区时进行数据聚合,而AggregatingMergeTree引擎支持自定义聚合函数,常用于物化视图。在数据处理过程中,各引擎都遵循在分区级别上进行操作的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建

CREATE TABLE partition_v3(
ID String,
URL String,
EventTime Date
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(EventTime)
ORDER BY ID
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name (
name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
name2 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
省略...
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, 省略...]

注意:MergeTree表引擎建立时,ORDER BY是必写的。
        (1)PARTITION BY [选填]:分区键,用于指定表数据以何种标准进行分区。分区键既可以是单个列字段,也可以通过元组的形式使用多个列字段,同时它也支持使用列表达式。如果不声明分区键,则ClickHouse会生成一个名为all的分区。
        (2)ORDER BY [必填]:排序键,用于指定在一个数据片段内,数据以何种标准排序。默认情况下主键(PRIMARY KEY)与排序键相同。排序键既可以是单个列字段,例如ORDERBY CounterID, 也 可 以 通 过 元 组 的 形 式 使 用 多 个 列 字 段, 例 如 ORDER BY(CounterID,EventDate)。 当 使 用 多 个 列 字 段 排 序 时, 以 ORDER BY(CounterID,EventDate)为例,在单个数据片段内,数据首先会以CounterID排序,相同CounterID的数据再按EventDate排序。
        (3)PRIMARY KEY [选填]:主键,顾名思义,声明后会依照主键字段生成一级索引,用于加速表查询。默认情况下,主键与排序键(ORDER BY)相同,所以通常直接使用ORDER BY代为指定主键,无须刻意通过PRIMARY KEY声明。所以在一般情况下,在单个数据片段内,数据与一级索引以相同的规则升序排列。与其他数据库不同,MergeTree主键允许存在重复数据(ReplacingMergeTree可以去重)。

ReplacingMergeTree(去重)

(1)使用ORBER BY排序键作为判断重复数据的唯一键。
(2)只有在合并分区的时候才会触发删除重复数据的逻辑。
(3)以数据分区为单位删除重复数据。当分区合并时,同一分区内的重复数据会被删除;不同分区之间的重复数据不会被删除。
(4)在进行数据去重时,因为分区内的数据已经基于ORBER BY进行了排序,所以能够找到那些相邻的重复数据。
(5)数据去重策略有两种:
•如果没有设置ver版本号,则保留同一组重复数据中的最后一行。
•如果设置了ver版本号,则保留同一组重复数据中ver字段取值最大的那一行。


SummingMergeTree(聚合)

(1)    用ORBER BY排序键作为聚合数据的条件Key。
(2)    ORDER BY 可以与 PRIMARY KEY 不同
(3)只有在合并分区的时候才会触发汇总的逻辑。
(4)以数据分区为单位来聚合数据。当分区合并时,同一数据分区内聚合Key相同的数据会被合并汇总,而不同分区之间的数据则不会被汇总。
(5)如果在定义引擎时指定了columns汇总列(非主键的数值类型字段),则SUM汇总这些列字段;如果未指定,则聚合所有非主键的数值类型字段。
(6)在进行数据汇总时,因为分区内的数据已经基于ORBER BY排序,所以能够找到相邻且拥有相同聚Key的数据。
(7)在汇总数据时,同一分区内,相同聚合Key的多行数据会合并成一行。其中,汇总字段会进行SUM计算;对于那些非汇总字段,则会使用第一行数据的取值。
(8)支持嵌套结构,但列字段名称必须以Map后缀结尾。嵌套类型中,默认以第一个字段作为聚合Key。除第一个字段以外,任何名称以Key、Id或Type为后缀结尾的字段,都将和第一个字段一起组成复合Key。

AggregatingMergeTree

(1)用ORBER BY排序键作为聚合数据的条件Key。
(2)使用AggregateFunction字段类型定义聚合函数的类型以及聚合的字段。
(3)只有在合并分区的时候才会触发聚合计算的逻辑。
(4)以数据分区为单位来聚合数据。当分区合并时,同一数据分区内聚合Key相同的数据会被合并计算,而不同分区之间的数据则不会被计算。
(5)在进行数据计算时,因为分区内的数据已经基于ORBER BY排序,所以能够找到那些相邻且拥有相同聚合Key的数据。
(6)在聚合数据时,同一分区内,相同聚合Key的多行数据会合并成一行。对于那些非主键、非AggregateFunction类型字段,则会使用第一行数据的取值。
(7)AggregateFunction类型的字段使用二进制存储,在写入数据时,需要调用*State函数;而在查询数据时,则需要调用相应的*Merge函数。其中,*表示定义时使用的聚合函数。
(8)AggregatingMergeTree通常作为物化视图的表引擎,与普通MergeTree搭配使用。
 

### 修改配置 在ClickHouse中,修改配置通常涉及对`config.xml`文件的编辑。该文件位于安装目录下的`/etc/clickhouse-server/`路径中。可以通过修改此文件中的参数来调整ClickHouse的行为。 例如,若想更改监听的IP地址或端口,可以在`<listen_host>`标签内进行设置: ```xml <listen_host>0.0.0.0</listen_host> ``` 对于更高级的设置,如调整内存限制、查询复杂度控制等,可以修改以下相关参数: - `<max_memory_usage>`:设置单个查询的最大内存使用量。 - `<max_rows_to_group_by>`:限制GROUP BY操作的最大行数[^1]。 完成修改后,需要重启ClickHouse服务以使更改生效。 ### 数据操作 #### 添加列 如果需要向现有表中添加新列,可以使用`ALTER TABLE`语句结合`ADD COLUMN`子句。例如,向`t_order_rmt`表中添加一个名为`status`的新列,其数据类型为`String`: ```sql ALTER TABLE t_order_rmt ADD COLUMN status String; ``` #### 删除列 同样地,删除表中的某一列也可以通过`ALTER TABLE`语句配合`DROP COLUMN`子句实现。比如,要从`t_order_rmt`表中移除之前添加的`status`列: ```sql ALTER TABLE t_order_rmt DROP COLUMN status; ``` #### 删除表 当不再需要某个表时,可以通过执行`DROP TABLE`命令来删除它。这将永久性地从数据库中移除指定的表及其所有数据: ```sql DROP TABLE t_order_rmt; ``` ### 表结构优化 为了确保ClickHouse能够高效运行,合理设计表结构至关重要。以下是几种常见的表结构优化方法: #### 选择合适的引擎 根据业务需求选择适合的数据表引擎非常重要。对于大多数场景,推荐使用`MergeTree`家族的引擎,因为它们支持分区、索引以及高效的合并策略。特别是`ReplacingMergeTree`,它可以自动清理重复的数据记录,非常适合处理具有时间戳字段的日志数据[^3]。 #### 分区与排序键 合理利用分区功能可以帮助进一步提升查询性能。通过定义合适的分区键(`PARTITION BY`),可以将数据划分为多个物理部分,从而加快特定范围内的查询速度。此外,正确设置排序键(`ORDER BY`)有助于减少磁盘I/O并加速数据检索过程。对于`t_order_rmt`表来说,按照`create_time`进行分区,并且基于`(id, sku_id)`进行排序是一个不错的选择[^3]。 #### 合理规划分片 分片是提高大规模部署环境下系统可扩展性和可用性的关键手段之一。通过将大表拆分成多个较小的部分分布在不同的节点上,不仅可以分散负载还能增强系统的容错能力。创建分布式表时需明确指定分片键,这样ClickHouse就能依据该键值决定如何分布数据至各个分片上[^1]。 #### 压缩与编码 最后但同样重要的是,考虑采用压缩算法和适当的列编码方式以节省存储空间并加快读取速度。某些列类型可能更适合特定类型的编码方案;例如,数值型字段可能会受益于Delta编码或者LZ4压缩等技术的应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值