clickhouse学习笔记(三)常见表引擎

目录

[一、 MergeTree系列引擎](#一、 MergeTree系列引擎)

1、MergeTree

数据TTL

[(1) 列级别 TTL](#(1) 列级别 TTL)

[(2) 表级别 TTL](#(2) 表级别 TTL)

存储策略

2、ReplacingMergeTree

3、CollapsingMergeTree

4、VersionedCollapsingMergeTree

5、SummingMergeTree

6、AggregatingMergeTree

[二、 外部存储类引擎](#二、 外部存储类引擎)

1、HDFS表引擎

2、mysql表引擎

3、JDBC表引擎

[4、Kafka 表引擎](#4、Kafka 表引擎)

5、File表引擎

三、内存类型引擎

1、memory表引擎

2、set表引擎

3、join表引擎

4、buffer表引擎

四、日志类型引擎

1、TinyLog表引擎

[2、StripeLog 表引擎](#2、StripeLog 表引擎)

3、Log表引擎

五、接口类型引擎

[1、Merge 表引擎](#1、Merge 表引擎)

[2、Dictionary 表引擎](#2、Dictionary 表引擎)

[3、Distributed 表引擎](#3、Distributed 表引擎)

六、其他引擎

[1、live view](#1、live view)

2、Null

3、URL


在大数据分析领域,ClickHouse以其卓越的查询性能和高效的列式存储机制而著称。其背后的核心技术之一便是多样化的表引擎,它们针对不同的数据访问模式和存储需求进行了优化。本文旨在深入探讨ClickHouse中的各种表引擎,帮助你更好地理解它们的特性和应用场景

一、 MergeTree系列引擎

MergeTree系列是ClickHouse中最为强大和常用的引擎,适用于大规模数据的高效存储和查询,特别是时间序列数据。这类引擎的特点是支持高效的写入和合并操作,能够处理高吞吐量的数据插入和复杂查询。

1、MergeTree

MergeTree 作为家族系列最基础的表引擎,提供了数据分区、一级索引和二级索引等功能。

数据TTL

TTL 即 Time To Live,表示数据的存活时间,而在 MergeTree 中可以为某个列字段或整张表设置 TTL。当时间到达时,如果是列字段级别的 TTL,则会删除这一列的数据;如果是整张表级别的 TTL,则会删除整张表的数据;如果同时设置,则会以先到期的为主。

无论是列级别还是表级别的 TTL,都需要依托某个 DateTime 或 Date 类型的字段,通过对这个时间字段的 INTERVAL 操作来表述 TTL 的过期时间,下面我们看一下设置的方式。

(1) 列级别 TTL

需要在定义表字段的时候,为它们声明了 TTL 表达式,主键字段不能被声明 TTL。

sql 复制代码
CREATE TABLE ttl_table_v1 (
    id String,
    create_time DateTime,
    code String TTL create_time + INTERVAL 10 SECOND,
    type UInt8 TTL create_time + INTERVAL 10 SECOND 
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY id
(2) 表级别 TTL
sql 复制代码
CREATE TABLE ttl_table_v2 (
    id String,
    create_time DateTime,
    code String TTL create_time + INTERVAL 1 MINUTE,
    type UInt8
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY create_time
TTL create_time + INTERVAL 1 DAY

建表的时候增加表级别的 TTL ,当触发 TTL 清理时,那些满足过期时间的数据行将被整行删除。TTL 支持修改,例如:

sql 复制代码
ALTER TABLE ttl_table_v2 MODIFY TTL create_time INTERVAL + 3 DAY

表级别的 TTL 不支持取消。

存储策略

ClickHouse 19.15 版本之前,MergeTree 只支持但路径存储,所有的数据都会被写入 config.xml 配置中 path 指定的路径下,即使服务器挂载了多块磁盘,也无法有效利用这些存储空间。19.15版本之后 MergeTree 实现了自定义存储策略的功能,支持以数据分区为最小移动单位,将分区目录写入多块磁盘目录。

三大存储侧策略:

  • 默认策略:MergeTree 原本的存储策略,无须任何配置,所有分区会自动保存到 config.xml 配置中 path 指定的路径下。
  • JBOD 策略:这种策略适合服务器挂载了多块磁盘,但没有做 RAID 的场景。数据可靠性需要利用副本机制保障。
  • HOT/COLD 策略:这种策略适合服务器挂载了不同类型磁盘的场景。HOT 区域使用 SSD 这类高性能存储媒介,注重存储性能;COLD 区域使用 HDD 这类高容量存储媒介,注重存取经济性。数据会先写入 HOT 累积到阈值之后自行移动到 COLD 区。
2、ReplacingMergeTree

支持数据的更新和删除,通过版本控制来标记过期数据, MergeTree 拥有主键,但没有唯一约束,如果不希望数据表中有重复数据的场景可以使用 ReplacingMergeTree ,它可以在合并分区时删除重复的数据

创建方式:

sql 复制代码
ENGINE = ReplacingMergeTree(ver)

里面的参数 ver 是选填的,可以指定一个整型、Date、DateTime 的字段作为版本号,这个参数决定了去除重复数据时所使用的算法。

创建一个ReplacingMergeTree 数据表:

sql 复制代码
CREATE TABLE replace_table (
    id String,
    code String,
    create_time DateTime
) ENGINE = ReplacingMergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY (id, code)
PRIMARY KEY id

上文中的order by 是去除重复数据的关键,数据会基于id 和 code 两个字段进行去重

测试如下

sql 复制代码
INSERT INTO replace_table 
VALUES ('A001', 'C1', '2020-11-10 15:00:00'),
       ('A001', 'C1', '2020-11-11 15:00:00'),
       ('A001', 'C100', '2020-11-12 15:00:00'),
       ('A001', 'C200', '2020-11-13 15:00:00'),
       ('A002', 'C2', '2020-11-14 15:00:00'),
       ('A003', 'C3', '2020-11-15 15:00:00')

create_time 为 2020-11-10 15:00:00、2020-11-11 15:00:00 的两条数据的 id 和 code 是重复的,因此会进行去重,只保留重复数据的最后一条

触发所有分区合并:

sql 复制代码
optimize TABLE table_name FINAL

总结一下 ReplacingMergeTree 的使用逻辑:

  • 使用 ORDER BY 排序键作为判断数据重复的唯一键;
  • 当导入同一分区目录时,会直接进行去重;
  • 当导入不同分区目录时,不会进行去重,只有当分区目录合并时,属于同一分区内的重复数据才会去重;但是不同分区内的重复数据不会被删除;
  • 在进行数据去重时,因为分区内的数据已经是基于 ORDER BY 排好序的,所以能很容易地找到那些相邻的重复的数据;
  • 数据去重策略有两种:如果没有设置 ver 版本号,则保留同一组重复数据中的最后一条;如果设置了 ver 版本号,则保留同一组重复数据中 ver 字段取值最大的那一行。
3、 CollapsingMergeTree

CollapsingMergeTree(折叠合并树) 就是一种通过以增代删的思路,支持行级数据修改和删除的表引擎。它通过定义一个 sign 标记位字段,记录数据行的状态。如果 sign 标记为 1,则表示这是一行有效数据;如果 sign 标记为 -1,则表示这行数据要被删除。当 CollapsingMergeTree 分区合并时,同一数据分区内,sign 标记为 1 和 -1 的一组数据(ORDER BY 字段对应的值相同)会被抵消删除。

创建方法

sql 复制代码
ENGINE = CollapsingMergeTree(sign)

sign 用于指定一个 Int8 类型的标志位字段,一个完整的 CollapsingMergeTree 数据表声明如下:

sql 复制代码
CREATE TABLE collapse_table (
    id String,
    code Int32,
    create_time DateTime,
    sign Int8
) ENGINE = CollapsingMergeTree(sign)
PARTITION BY toYYYYMM(create_time)
ORDER BY id

CollapsingMergeTree 在折叠数据时遵循如下规则:

  • 如果 sign = 1 比 sign = -1 的数据多一行,则保留最后一行 sign = 1 的数据
  • 如果 sign = -1 比 sign = 1 的数据多一行,则保留第一行 sign = -1 的数据
  • 如果 sign = 1 和 sign = -1 的数据行一样多,并且最后一行是 sign = 1,则保留第一行 sign = -1 和最后一行 sign = 1 的数据
  • 如果 sign = 1 和 sign = -1 的数据行一行多,并且最后一行是 sign = -1,则什么也不保留
  • 其余情况,ClickHouse 会打印告警日志,但不会报错,在这种情形下打印结果不可预知

当然折叠数据并不是实时触发的,和所有的其它 MergeTree 变种表引擎一样,这项特性只有在多个分区目录合并的时候才会触发,触发时属于同一分区的数据会进行折叠。而在分区合并之前,用户还是可以看到旧数据的,就像上面演示的那样。

如果不想看到旧数据,那么可以在聚合的时候可以改变一下策略:

sql 复制代码
-- 原始 SQL 语句
SELECT id, sum(code), count(code), avg(code), uniq(code) 
FROM collapse_table GROUP BY id

-- 改成如下
SELECT id, sum(code * sign), count(code * sign), avg(code * sign), uniq(code * sign)
FROM collapse_table GROUP BY id HAVING sum(sign) > 0

或者在查询数据之前使用 optimize TABLE table_name FINAL 命令强制分区合并,但是这种方法效率极低,在实际生产环境中慎用

注意:

CollapsingMergeTree 的处理机制所要求 sign = 1 和 sign = -1 的数据相邻,而分区内的数据严格按照

ORDER BY 排序,要实现 sign = 1 和 sign = -1 的数据相邻,则只能严格按照顺序写入。

如果数据的写入顺序是单线程执行的,则能够比较好的控制写入顺序;但如果需要处理的数据量很大,数据的写入程序通常是多线程的,那么此时就不能保障数据的写入顺序了。而在这种情况下,CollapsingMergeTree 的工作机制就会出现问题

​​​​​​​4、VersionedCollapsingMergeTree

VersionedCollapsingMergeTree 表引擎的作用和 CollapsingMergeTree 完全相同,它们的不同之处在于 VersionedCollapsingMergeTree 对数据的写入顺序没有要求,在同一个分区内,任意顺序的数据都可以完成折叠操作。那么 VersionedCollapsingMergeTree 是如何做到这一点的呢?其实从它的名字就能看出来,因为相比 CollapsingMergeTree 多了一个 Versioned,那么显然就是通过版本号(version)解决的。

在定义 VersionedCollapsingMergeTree 数据表的时候,除了指定 sign 标记字段之外,还需要额外指定一个 UInt8 类型的 ver 版本号字段。

sql 复制代码
ENGINE = VersionedCollapsingMergeTree(sign, ver)

一个完整的 VersionedCollapsingMergeTree 表定义如下:

sql 复制代码
CREATE TABLE ver_collapse_table (
    id String,
    code Int32,
    create_time DateTime,
    sign Int8,
    ver UInt8
) ENGINE = CollapsingMergeTree(sign, ver)
PARTITION BY toYYYYMM(create_time)
ORDER BY id

提问:VersionedCollapsingMergeTree 是如何使用版本号字段的呢?

答:在定义 ver 字段之后,VersionedCollapsingMergeTree 会自动将 ver 作为排序条件并增加到 ORDER BY 的末端。以上面的 ver_collapse_table 为例,在每个分区内,数据会按照 ORDER BY id, ver DESC 排序。所以,无论写入时数据的顺序如何,在折叠处理时,都能回到正确的顺序。

5、SummingMergeTree

能够在合并分区的时候按照预先定义的条件聚合汇总数据,减少查询时的计算开销和数据行数。

主要使用的场景是用户只关心汇总结果,不关心明细数据,并且数据汇总条件是预先明确的场景(GROUP BY 条件明确,且不会随意改变)

创建方法

sql 复制代码
ENGINE = SummingMergeTree((col1, col2, col3, ...))

其中 col1、col2 为 columns 参数值,这是一个选填参数,用于设置除主键外的其它数值类型字段,以指定被 SUM 汇总的列字段。如果不填写此参数,则会将所有非主键的数值类型字段进行汇总,下面就来创建一张 SummingMergeTree 表:

sql 复制代码
CREATE TABLE summing_table (
    id String,
    city String,
    v1 UInt32,
    v2 Float64,
    create_time DateTime
) ENGINE = SummingMergeTree()
PARTITION BY toYYYYMM(create_time)
PRIMARY KEY id
ORDER BY (id, city)

如果导入同一分区目录的数据有重复的,那么直接就聚合了,不同分区目录则不会聚合,而是在合并生成新分区目录的时候,再对属于同一分区的多个分区目录里的数据进行聚合。另外 SummingMergeTree 也支持嵌套类型的字段,在使用嵌套类型字段时,需要被 SUM 汇总的字段必须以以 Map 后缀结尾。

总结

  • 只有 ORDER BY 排序键作为聚合数据的条件 Key
  • 写入同一分区目录的数据会聚合之后在写入,而属于同一分区的不同分区目录的数据,则会在合并触发时进行汇总
  • 不同分区的数据不会汇总到一起
  • 如果在定义引擎时指定了 columns 汇总列(非主键的数值类型字段),则 SUM 会汇总这些列字段;如果未指定,则聚合所有非主键的数值类型字段
  • 在进行数据汇总时,因为分区内的数据已经基于 ORDER BY 进行排序,所以很容易找到相邻也拥有相同 Key 的数据
  • 在汇总数据时,同一分区内相同聚合 key 的多行数据会合并成一行,其中汇总字段会进行 SUM 计算;对于那些非汇总字段,则会使用第一行数据的取值
  • 支持嵌套结构,但列字段名称必须以 Map 后缀结尾,并且默认以第一个字段作为聚合 Key。并且除了第一个字段以外,任何名称以 key、Id 或者 Type 为后缀结尾的字段都会和第一个字段组成复合 Key
6、AggregatingMergeTree

专为聚合查询设计,能够在插入数据时进行预聚合,加快GROUP BY查询。

AggregatingMergeTree 是 SummingMergeTree 升级版,有些数据立方体的意思,核心思想是以空间换时间的方法提升查询性能。首先,它能够在合并分区的时候按照预先定义的条件聚合数据。同时,根据预先定义的聚合函数计算数据并通过二进制的格式存入表内。通过将同一分组下的多行数据预先聚合成一行,既减少了数据行,又降低了后续聚合查询的开销。

创建方法

sql 复制代码
ENGINE = AggregatingMergeTree()

AggregatingMergeTree 没有任何额外的设置参数,在分区合并时,在每个数据分区内,会按照 ORDER BY 聚合。经常结合物化视图方式实现,首先创建底表:

sql 复制代码
CREATE TABLE agg_table_basic (
    id String,
    city String,
    code String,
    value UInt32
) ENGINE = MergeTree()
PARTITION BY city
ORDER BY (id, city)

通常使用 MergeTree 作为底表,用于存储全量的明细数据,并以此对外提供实时查询。接着,创建一张物化视图:

sql 复制代码
CREATE MATERIALIZED VIEW agg_view 
ENGINE = AggregatingMergeTree()
PARTITION BY city
ORDER BY (id, city)
AS SELECT
    id, city,
    uniqState(code) AS code,
    sumState(value) AS value
FROM agg_table_basic
GROUP BY id, city

物化视图使用 AggregatingMergeTree 表引擎,用于特定场景的数据查询,相比 MergeTree,它拥有更高的性能。数据会自动同步到物化视图,并按照 AggregatingMergeTree 的引擎的规则进行处理,查询只对 agg_view 查询即可。

二、 外部存储类引擎

这类引擎用于与外部数据源的集成,使得ClickHouse可以直接读写其他数据库或文件系统中的数据。

1、HDFS表引擎

注意:我们需要关闭 HDFS 的 Kerberos 认证,因为 HDFS 表引擎还不支持 Kerberos,然后在 HDFS 上创建用于存放文件的目录。

sql 复制代码
CREATE TABLE hdfs_table1 (
    id UInt32,
    code String,
    name String
) ENGINE = HDFS('hdfs://localhost:6666/clickhouse/hdfs_table1', 'CSV')
-- HDFS('HDFS 的文件存储路径', '文件格式,如 CSV、TSV、JSON 等等')
-- 注:数据表的名字和 HDFS 文件系统上的文件名可以不一致
2、mysql表引擎
sql 复制代码
CREATE TABLE clickhouse_trade_info (
    id UInt32,
    column1 type,
    column2 type,
    ......
) ENGINE = MySQL('localhost:3306', 'default', 'trade_info', 'root', '123456')
-- 显然这几个参数的含义不需要多说,但还有两个可选参数 replace_query 和 on_duplicate_clause
-- replace_query 默认为 0,如果设置为 1,会用 REPLACE INTO 代替 INSERT INTO
-- on_duplicate_clause 默认为 0,对应 MySQL 的 ON DUPLICATE KEY 语法,如果想启用该设置,那么需要设置为 1
3、JDBC表引擎

相对于 MySQL 表引擎而言,JDBC 表引擎不仅可以对接 MySQL 数据库还能够与 PostgreSQL、SQLite 和 H2 数据库对接。但是,JDBC 表引擎无法单独完成所有的工作,他需要依赖名为 clickhouse-jdbc-bridge 的查询代理服务。自行研究吧

sql 复制代码
ENGINE = JDBC('jdbc:url', 'database', 'table')
4、Kafka 表引擎

clickhouse支持kafka表引擎,kafka有三种语义

  • 最多一次(At Most Once):可能出现消息丢失的情况,因为在这种情形下,一条消息在消费端最多被接收一次
  • 最少一次(At Least Once):可能出现消息重复的情况,因为在这种情形下,一条消息在消费端允许被接收多次
  • 精确一次(Exactly Once):数据不多不少,一条消息在消费端恰好被消费一次,这也是最理想的情况,因为消息不可能百分之百不丢失

kafka表引擎目前还不支持精确一次(Exactly Once)

sql 复制代码
ENGINE = Kafka()
SETTINGS kafka_broker_list = 'host:port,...',
         kafka_topic_list = 'topic1,topic2',
         kafka_group_name = 'group_name',
         kafka_format = 'data_format[,]',
         [kafka_row_delimiter = 'delimiter_symbol',]
         [kafka_schema = '',]
         [kafka_num_consumers = N,]
         [kafka_skip_broken_message = N,]
         [kafka_commit_every_batch = N]

其中带有方括号的表示选填项,下面依次介绍这些参数的作用:

  • kafka_broker_list:表示 Broker 服务的地址列表,多个地址之间使用逗号分割
  • kafka_topic_list:表示订阅的消息主题的名称列表,多个主题之间使用逗号分割,多个主题中的数据均被消费
  • kafka_group_name:表示消费者组的名称,表引擎会依据此名称创建消费者组
  • kafka_format:表示用于解析消息的数据格式,在消息的发送端,必须按照此格式发送消息。而数据格式也必须是 ClickHouse 提供的格式之一,例如 TSV、JSONEachRow 和 CSV 等
  • kafka_row_delimiter:表示判定一行数据的结束符,默认为 '\0'
  • kafka_schema:对应 Kafka 的 schema 参数
  • kafka_num_consumers:表示消费者的数据量,默认值为 1,表引擎会依据此参数在消费者组中开启相应数量的消费者线程,当然线程数不要超过分区数,否则没有意义。因为在 kafka 的主题中,一个分区只能被某个消费者组里面的一个消费者消费(如果想被多个消费者消费,那么这些消费者一定要隶属于不同的消费者组)
  • kafka_skip_broken_message:当表引擎按照预定格式解析数据出现错误时,允许跳过失败的数据的行数,默认值为 0,即不允许任何格式错误的情形发生。在此种情形下,只要 kafka 主题中存在无法解析的数据,数据表都将不会接收任何数据。如果将其设置成非 0 的正整数,例如设置为 10,则表示只要 kafka 主题中存在无法解析的数据的总数小于 10,数据表就能正常接收消息数据,而解析错误的数据会被自动跳过
  • kafka_commit_every_batch:表示执行 kafka commit 的频率,因此这里提交偏移量的方式是手动提交,默认值为 0,即当一整个 Block 块完全写入数据表后才执行一次 commit。如果设置为 1,则每写完一个 Batch 批次的数据就会执行一次 kakfa commit(一次 Block 写入操作,由多次 Batch 写入操作而成)
5、File表引擎

File 表引擎能够直接读取本地文件的数据,例如系统生成的文件,还可以将数据导出为本地文件

File 表引擎的声明方式如下:

sql 复制代码
ENGINE = File(clickhouse支持的数据格式,例如TSV,CSV,JSONeachRow等),例如

CREATE TABLE test_file_table
(
    `id` UInt32,
    `name` String
)
ENGINE = File('CSV')

由上可见没有文件路径**,** 因为 File 表引擎的数据文件只能保存在 config.xml 配置中由 path 指定的路径下,也就是和其它的数据表在同一个路径下。

每张 File 数据表均由目录和文件组成,其中目录以表的名称命名,而数据文件则以 data.<format> 命名,比如 data.CSV、data.TSV 等等

三、内存类型引擎

除了 Memory 表引擎之外,其余的几款内存表引擎都会将数据写入磁盘,因为为了防止数据丢失,所以也提供了这种故障恢复手段。而在数据表被加载时,它们会将数据全部加载至内存,以供查询。

1、memory表引擎

Memory 表引擎直接将数据保存在内存中,数据即不会被压缩也不会被格式转换,因为基于内存,所以服务重启后会丢失。常见用途为测试和clickhouse内部用来集群间分发数据的存储载体

Memory 表引擎测试表:

sql 复制代码
CREATE TABLE test_memory_table
(
    `id` UInt32,
    `name` String
)
ENGINE = Memory()

当数据被写入后,磁盘上不会创建任何文件,如果服务重启那这张表也会消失

2、set表引擎

Set 表引擎是拥有物理存储的,数据首先会被写入内存,然后被同步到磁盘文件中。所以服务重启之后它的数据不会丢失,当数据表被重新状态时,文件数据会再次被全量加载到内存中,

sql 复制代码
CREATE TABLE test_set_table
(
    `id` UInt32
)
ENGINE = Set()

set表支持insert,不支持select,常用在查询条件的in查询里,如下

sql 复制代码
select age,name,id from tmp_table where arr in set_table
3、join表引擎

join表数据也会先写入内存,然后同步到磁盘,且支持select操作,它的主要用途是在内存中缓存较小的数据集,以便可以快速地与较大的数据集进行JOIN操作。Join表引擎不是用于存储大量数据的主要表,而是作为辅助表,以加速查询性能

sql 复制代码
CREATE TABLE test_join_table
(
    `id` UInt32,
    `name` String
)
ENGINE = Join(join_strictness, join_type, key1[, key2, ...])


案例如下
CREATE TABLE test_join_table
(
    `id` UInt32,
    `name` String
)
ENGINE = Join(ANY,LEFT,id)

其中各参数的含义如下:

  • join_strictness:连接精度,它决定了 JOIN 查询在连接数据时所使用的策略,目前支持 ALL、ANY、SEMI、ANTI 四种类型
  • join_type:连接类型,它决定了 JOIN 查询在组合左右两个数据集合的策略,目前支持 INNER、LEFT、RIGHT 和 FULL 四种类型
  • join_key:连接键,它决定了使用哪个列字段进行关联
4、buffer表引擎

Buffer 表引擎完全使用内存装载数据,不支持文件的持久化存储,所以当服务重启之后,表内的数据会被清空。Buffer 表引擎不是为了面向查询场景而设计的,它的作用是充当缓冲区的角色。

Buffer 表引擎的声明方式如下:

sql 复制代码
ENGINE = Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)

里面参数的作用如下:

  • database:目标表的数据库
  • table:目标表,Buffer 表内的数据会自动刷新到目标表
  • num_layers:可以理解为线程数,Buffer 表会按照 num_layers 的数量开启线程,以并行的方式将数据刷新到目标表,官方建议设置为 16

Buffer 表并不是实时刷新数据的,只有在阈值条件满足时才会刷新,阈值条件由三个最小和最大值组成,含义如下:

  • min_time 和 max_time:时间条件的最小值和最大值,单位为秒,从第一次向表内写入数据时开始计算
  • min_rows 和 max_rows:数据行数条件的最小值和最大值
  • min_bytes 和 max_bytes:数据大小的最小值和最大值,单位为字节

针对以上条件,Buffer 表刷新数据的判断依据有三个,满足其中任意一个就会刷新数据:

  • 三组条件中所有最小阈值都已满足,则触发刷新动作
  • 三组条件中有一个最大阈值满足(这里是超过最大值),则触发刷新动作
  • 如果写入一批数据的行数大运 max_rows 或者数据大小大于 max_bytes,则数据直接写入目标表

四、日志类型引擎

日志的表引擎也有一些共性特征:比如均不支持索引、分区等高级特性,不支持并发读写等等。当针对一张日志表写入数据时,针对这张表的查询会被阻塞,直至写入动作结束。但它们同时也拥有切实的物理存储,数据会被保存到本地文件中

1、TinyLog表引擎

TinyLog 是日志家族系列中性能最低的表引擎,它的存储结构由数据文件和元数据两部分组成。

TinyLog 表引擎测试表:

sql 复制代码
CREATE TABLE test_tinylog_table
(
    `id` UInt32,
    `name` String
)
ENGINE = TinyLog()
2、StripeLog 表引擎

StripeLog 对比 TinyLog 拥有更高的查询性能。

StripeLog 表引擎测试表:

sql 复制代码
CREATE TABLE test_stripelog_table
(
    `id` UInt32,
    `name` String
)
ENGINE = StripeLog()
3、Log表引擎

Log 表引擎结合了 TinyLog 表引擎和 StripeLog 表引擎的长处,是日志引擎中性能最高的表引擎。由于拥有数据标记且各列数据独立存储,所以 Log 既能够支持并行查询,又能够按列按需读取。Log 表引擎测试表:

sql 复制代码
CREATE TABLE test_log_table
(
    `id` UInt32,
    `name` String
)
ENGINE = Log()

五、接口类型引擎

1、Merge 表引擎

Merge 表引擎就如同一层使用了门面模式的代理,它本身不存储任何数据,也不支持数据写入,它的作用就如同它的名字,即负责合并多个查询结果集。

Merge 表引擎的声明方式如下:

sql 复制代码
ENGINE = Merge(database, table_name)

其中 database 为数据库的名称,table_name 为数据表的名称,它支持使用正式则表达式,比如 ^ 表示合并所有以 test 为前缀的数据表

例如有日期分区命名的表test_table_2019、test_table_2020、test_table_2021、test_table_2022、test_table_2023、test_table_2024

sql 复制代码
-- test_table_2019 保存了 2019 年的数据
CREATE TABLE test_table_2019 (
    id String,
    create_time DateTime,
    code String
) ENGINE = MergeTree()
PARTITION BY toYYYYMM(create_time)
ORDER BY id;


2020-2024同上

然后创建 Merge 表将上面两张表结合,这里的 AS 相当于为 merge_test_table_2019_2024 指定表结构
显然这里会复制 test_table_2019 的表结构
CREATE TABLE merge_test_table_2019_2024 AS test_table_2019
ENGINE = Merge(currentDatabase(), '^test_table_20')
-- currentDatabase() 表示获取当前的数据库
上面的语句是将所有以^test_table_20开头的数据表合并。
2、Dictionary 表引擎

Dictionary 表引擎是数据字段的一层代理封装,它可以取代字典函数,让用户通过数据表查询字典。字典内的数据被加载后,会全部保存到内存中,所以使用 Dictionary 表对字典表性能不会有任何影响。

Dictionary 表引擎测试表:

sql 复制代码
CREATE TABLE tb_test_flat_dict
(
    `id` UInt32,
    `code` String,
    `name` String
)
ENGINE = Dictionary(dict_name)

dict_name对应一个已被加载的字典名称

3、Distributed 表引擎

Distributed 表引擎自身不存储任何数据,它能作为分布式表的一层透明代理,在集群内部自动开展数据的写入分发以及查询路由工作。

六、其他引擎

1、live view

从 19.14 版本开始,ClickHouse 提供了一种全新的视图:Live View。

Live View 是一种特殊的视图,虽然它并不属于表引擎,但是因为它与数据表息息相关,所以还是把 LiveView 归类到了这里。Live View 的作用类似事件监听器,它能够将一条 SQL 查询结果作为监控目标,当目标数据增加时,LiveView 可以及时发出响应。若要使用 Live View,首先需要将 allow_experimental_live_view 参数设置为 1

原始表

sql 复制代码
CREATE TABLE origin_table1
(
    `id` UInt32,
    `name` String
)
ENGINE = Log()

创建一张 Live View 表示:

sql 复制代码
CREATE LIVE VIEW lv_origin AS SELECT COUNT(*) FROM orign_table1

如此一来,Live View 就进入监听模式了。接着通过下面的命令可以看出实时监控结果:

sql 复制代码
WATCH lv_origin
2、Null

Null 表引擎的功能和作用,与 Unix 系统的空设备 /dev/null 很相似。如果用户向 Null 表写入数据,系统会正确返回,但是 Null 表会自动忽略数据,永远不会将它保存。如果不希望保留源表的数据,那么将原表设置成 Null 引擎将会是极好的选择。

3、URL

URL 表引擎的作用等价于 HTTP 客户端,他可以通过 HTTP/HTTPS 协议,直接访问远端的 REST 服务。当执行 SELECT 查询的时候,底层会将其转换成 GET 请求的远程调用。而执行 INSERT 查询的时候,会将其转换为 POST 请求的远程调用。URL 表引擎的声明方式如下:

sql 复制代码
ENGINE = URL(url, format)

其中,url 表示远端的服务地址,而 format 则是 Clickhouse 支持的数据格式,如 TSV、CSV 和 JSON 等。

相关推荐
z樾14 分钟前
Github界面学习
学习
道爷我悟了1 小时前
Vue入门-指令学习-v-html
vue.js·学习·html
NuyoahC1 小时前
算法笔记(十一)——优先级队列(堆)
c++·笔记·算法·优先级队列
计算机学姐2 小时前
基于SpringBoot+Vue的在线投票系统
java·vue.js·spring boot·后端·学习·intellij-idea·mybatis
彤银浦2 小时前
python学习记录7
python·学习
这可就有点麻烦了2 小时前
强化学习笔记之【TD3算法】
linux·笔记·算法·机器学习
少女忧2 小时前
51单片机学习第六课---B站UP主江协科技
科技·学习·51单片机
邓校长的编程课堂3 小时前
助力信息学奥赛-VisuAlgo:提升编程与算法学习的可视化工具
学习·算法
missmisslulu4 小时前
电容笔值得买吗?2024精选盘点推荐五大惊艳平替电容笔!
学习·ios·电脑·平板
yunhuibin4 小时前
ffmpeg面向对象——拉流协议匹配机制探索
学习·ffmpeg