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

目录

一、 MergeTree系列引擎

1、MergeTree

数据TTL

(1) 列级别 TTL

(2) 表级别 TTL

存储策略

2、ReplacingMergeTree

3、CollapsingMergeTree

4、VersionedCollapsingMergeTree

5、SummingMergeTree

6、AggregatingMergeTree

二、 外部存储类引擎

1、HDFS表引擎

2、mysql表引擎

3、JDBC表引擎

4、Kafka 表引擎

5、File表引擎

三、内存类型引擎

1、memory表引擎

2、set表引擎

3、join表引擎

4、buffer表引擎

四、日志类型引擎

1、TinyLog表引擎

2、StripeLog 表引擎

3、Log表引擎

 五、接口类型引擎

1、Merge 表引擎

2、Dictionary 表引擎

3、Distributed 表引擎

六、其他引擎

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。

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
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 支持修改,例如:

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 ,它可以在合并分区时删除重复的数据

创建方式:

ENGINE = ReplacingMergeTree(ver)

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

        创建一个ReplacingMergeTree 数据表:

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 两个字段进行去重

测试如下

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 是重复的,因此会进行去重,只保留重复数据的最后一条

触发所有分区合并:

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 字段对应的值相同)会被抵消删除。
创建方法

ENGINE = CollapsingMergeTree(sign)

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

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 语句
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 版本号字段。

ENGINE = VersionedCollapsingMergeTree(sign, ver)

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

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 条件明确,且不会随意改变)

创建方法

ENGINE = SummingMergeTree((col1, col2, col3, ...))

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

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

创建方法

ENGINE = AggregatingMergeTree()

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

CREATE TABLE agg_table_basic (id String,city String,code String,value UInt32
) ENGINE = MergeTree()
PARTITION BY city
ORDER BY (id, city)

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

CREATE MATERIALIZED VIEW agg_view 
ENGINE = AggregatingMergeTree()
PARTITION BY city
ORDER BY (id, city)
AS SELECTid, 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 上创建用于存放文件的目录。

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表引擎
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 的查询代理服务。自行研究吧

ENGINE = JDBC('jdbc:url', 'database', 'table')
4、Kafka 表引擎

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

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

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

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 表引擎的声明方式如下:

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 表引擎测试表:

CREATE TABLE test_memory_table
(`id` UInt32,`name` String
)
ENGINE = Memory()

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

2、set表引擎

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

CREATE TABLE test_set_table
(`id` UInt32
)
ENGINE = Set()

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

select age,name,id from tmp_table where arr in set_table
3、join表引擎

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

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 表引擎的声明方式如下:

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 表引擎测试表:

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

         StripeLog 对比 TinyLog 拥有更高的查询性能。
StripeLog 表引擎测试表:

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

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

CREATE TABLE test_log_table
(`id` UInt32,`name` String
)
ENGINE = Log()

 五、接口类型引擎

1、Merge 表引擎

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

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

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

-- 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 表引擎测试表:

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

原始表

CREATE TABLE origin_table1
(`id` UInt32,`name` String
)
ENGINE = Log()


创建一张 Live View 表示:

CREATE LIVE VIEW lv_origin AS SELECT COUNT(*) FROM orign_table1


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

WATCH lv_origin
2、Null


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

3、URL


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

ENGINE = URL(url, format)


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/24005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

「动态规划」如何求地下城游戏中,最低初始健康点数是多少?

174. 地下城游戏https://leetcode.cn/problems/dungeon-game/description/ 恶魔们抓住了公主并将她关在了地下城dungeon的右下角。地下城是由m x n个房间组成的二维网格。我们英勇的骑士最初被安置在左上角的房间里&#xff0c;他必须穿过地下城并通过对抗恶魔来拯救公主。骑士…

【Text2SQL 论文】C3:使用 ChatGPT 实现 zero-shot Text2SQL

论文&#xff1a;C3: Zero-shot Text-to-SQL with ChatGPT ⭐⭐⭐⭐ arXiv:2307.07306&#xff0c;浙大 Code&#xff1a;C3SQL | GitHub 一、论文速读 使用 ChatGPT 来解决 Text2SQL 任务时&#xff0c;few-shots ICL 的 setting 需要输入大量的 tokens&#xff0c;这有点昂贵…

基于GLM生成SQL,基于MOSS生成SQL,其中什么是GLM 什么是MOSS

GLM 和 MOSS 是两种不同的模型或系统&#xff0c;通常用在自然语言处理 (NLP) 和生成任务中&#xff0c;如生成 SQL 查询。让我们逐个解释它们的含义和用途&#xff1a; GLM (Generalized Language Model) GLM 是一种通用语言模型&#xff0c;设计用于处理和生成自然语言。以…

MacOS M系列芯片一键配置多个不同版本的JDK

第一步&#xff1a;下载JDK。 官网下载地址&#xff1a;Java Archive | Oracle 选择自己想要下载的版本&#xff0c;一般来说下载一个jdk8和一个jdk11就够用了。 M系列芯片选择这两个&#xff0c;第一个是压缩包&#xff0c;第二个是dmg可以安装的。 第二步&#xff1a;编辑…

eclipse插件开发(二)RCP第三方库的引入方式

RCP第三方库的引入 最近在RCP开发过程中遇到JSON串与对象互转的问题&#xff0c;如何像spring开发模式一样引入第三方库呢&#xff1f;eclipse插件开发中用到p2库&#xff0c;但也支持maven库的引入。关键在于.target这个关键文件。 .target 文件用于定义一个目标平台&#x…

民主测评要做些什么?

民主测评&#xff0c;作为一种重要的民主管理工具&#xff0c;旨在通过广泛征求群众意见&#xff0c;对特定对象或事项进行客观、公正的评价。它不仅是推动民主参与、民主监督的重要手段&#xff0c;也是提升治理效能、促进社会和谐的有效途径。以下将详细介绍民主测评的主要过…

常见的布局方法及优缺点

页面布局常用的方法有浮动、定位、flex、grid网格布局、栅格系统布局 浮动&#xff1a; 优点&#xff1a;兼容性好。 缺点&#xff1a;浮动会脱离标准文档流&#xff0c;因此要清除浮动。我们解决好这个问题即可。 绝对定位 优点&#xff1a;快捷。 缺点&#xff1a;导致子…

如何以非交互方式将参数传递给交互式脚本

文章目录 问题回答1. 使用 Here Document2. 使用 echo 管道传递3. 使用文件描述符4. 使用 expect 工具 参考 问题 我有一个 Bash 脚本&#xff0c;它使用 read 命令以交互方式读取命令参数&#xff0c;例如 yes/no 选项。是否有一种方法可以在非交互式脚本中调用这个脚本&…

vue用vite配置代理解决跨域问题(target、rewrite和changeOrigin的使用场景)

Vite的target、rewrite和changeOrigin的使用场景 1. target 使用场景&#xff1a;target 属性在 Vite 的 vite.config.ts 或 vite.config.js 文件的 server.proxy 配置中指定&#xff0c;用于设置代理服务器应该将请求转发到的目标地址。这通常是一个后端服务的API接口地址。…

Chrome 源码阅读:跟踪一个鼠标事件的流程

我们通过在关键节点打断点的方式&#xff0c;去分析一个鼠标事件的流程。 我们知道chromium是多进程模型&#xff0c;那么&#xff0c;我们可以推测&#xff1a;一个鼠标消息先从主进程产生&#xff0c;再通过跨进程通信发送给渲染进程&#xff0c;渲染进程再发送给WebFrame&a…

【FAS】《CN103106397B》

原文 CN103106397B-基于亮瞳效应的人脸活体检测方法-授权-2013.01.19 华南理工大学 方法 / 点评 核心方法用的是传统的形态学和模板匹配&#xff0c;亮点是双红外发射器做差分 差分&#xff1a;所述FPGA芯片控制两组红外光源&#xff08;一近一远&#xff09;交替亮灭&…

[力扣题解] 700. 二叉搜索树中的搜索

题目&#xff1a;700. 二叉搜索树中的搜索 思路 观察法 二叉搜索树的搜索操作&#xff0c;比较根节点的数值&#xff0c; 如果等于&#xff1a;找到了&#xff1b;大于根节点&#xff1a;在右子树&#xff0c;往右走&#xff1b;小于根节点&#xff1a;在左子树&#xff0c;…

【Java基础】线程方法

start()&#xff1a;启动线程&#xff0c;使线程进入就绪状态。 run()&#xff1a;线程执行的代码逻辑&#xff0c;需要重写该方法。 停止线程 void interrupt() 中断线程&#xff0c;让它重新去争抢cpu 如果目标线程长时间等待&#xff0c;则应该使用interrupt方法来中断等待…

RDMA (2)

iWARP(RDMA)怎么工作的 招式1:bypass内核 非iWARP时,当应用向网络适配器发出读或者写命令时,命令穿过用户空间以及内核空间,因此需要在用户空间和内核空间间进行切换。 iWARP使用RDMA,让应用直接将命令送达到网络适配器。这规避了对内核的调用,减少了开销和延迟。 招式2…

【Kubernetes】三证集齐 Kubernetes实现资源超卖(附镜像包)

目录 插叙前言一、思考和原理二、实现步骤0. 资料包1. TLS证书签发2. 使用 certmanager 生成签发证书3. 获取secret的内容 并替换CA_BUNDLE4.部署svc deploy 三、测试验证1. 观察pod情况2. 给node 打上不需要超售的标签【可以让master节点资源不超卖】3. 资源实现超卖4. 删除还…

[补题记录]Leetcode 209.长度最小的子数组

传送门&#xff1a;长度最小的子数组 Problem/题意 给定一个整数数组和一个整数 target&#xff0c;要求算出数组中最小长度的连续子数组&#xff0c;数组元素的和大于等于 target。 Thought/思路 题目要求维护最小的长度&#xff0c;因此我们希望&#xff1a;当条件不满足…

IP域名关系的研究与系统设计(学习某知名测绘系统)

IP域名关系库管理包括域名库检索和whois库检索&#xff0c;详情如下。 域名库检索支持以下5项功能&#xff1a; 1.通过过滤器检索 筛选条件包含IP地址、口令、工具名称、可利用的漏洞编号、创建时间&#xff1b; 2.通过关键字检索 在查询框中输入域名库名称的部分关键词&a…

计算机组成结构—IO系统概述

目录 一、I/O 系统的发展 1. 早期阶段 2. 接口模块和 DMA 阶段 3. 通道结构阶段 4. 处理机阶段 二、I/O 系统的组成 1. I/O 软件 2. I/O 硬件 三、I/O 设备 1. I/O 设备分类 2. I/O 设备的组成 在计算机中&#xff0c;除 CPU 和主存两大模块之外&#xff0c;第三个重…

Apple开发者应用商店(AppStore)描述文件及ADHOC描述文件生成

创建AD HOC描述文件 1.选中Profiles,然后点击加号创建 2.创建已注册设备可安装描述文件 3.选择要注册的id 4.选择证书 5.选择设备 6.输入文件名,点击生成 7.生成成功,点击下载

TCP为什么握手是三次,而挥手是四次

TCP&#xff08;传输控制协议&#xff09;使用三次握手&#xff08;3WHS&#xff09;来建立一个可靠的连接&#xff0c;并使用四次挥手&#xff08;4WHS&#xff09;来终止连接。以下是每个步骤的详细解释&#xff1a; 三次握手&#xff08;3WHS&#xff09;建立连接&#xff…