ClickHouse介绍
ClickHouse
是由俄罗斯的Yandex
公司开发的一款快速、可扩展的列式数据库管理系统。它专门针对OLAP
场景设计,在海量数据分析和查询方面具有出色的性能表现,同时还能支持实时数据插入和更新。ClickHouse
采用了面向列的存储方式,具有较高的压缩比和查询速度。它支持SQL
语言,并提供了一系列丰富的函数库,可满足各种复杂的数据分析需求。同时,ClickHouse
还支持数据分区和分片,可实现横向扩展ClickHouse
使用C++
编写,可在Linux
和Windows
等操作系统上运行。它还支持RESTful API
和JDBC
等多种接口,方便与其他系统进行集成。由于其出色的性能和可扩展性,ClickHouse被许多企业用于大规模数据处理和分析,如Yandex
、CloudFlare
、Kenshoo
等- 在使用
ClickHouse
时,我们可以尽情的存储我们的海量数据,也可以毫不忌讳的直接把海量数据使用SQL
进行计算和统计 - 但是,对于数据变动来说,
ClickHouse
并不建议大家使用数据更新和删除的SQL语句,虽然他们提供了这些语句
为什么不推荐更新和删除
ClickHouse
并不鼓励使用UPDATE
和DELETE
语句进行数据的更新和删除操作。主要原因有以下几点:
-
ClickHouse
是一个面向列的数据库,其存储和查询数据的方式与传统的关系型数据库有很大不同。因此,更新和删除操作需要涉及到多个列,同时也会影响到索引的维护和数据的压缩等方面,从而影响到整个系统的性能。 -
ClickHouse
更适合于高并发的OLAP
场景,即大量的读操作
和少量的写操作
,因此并不需要频繁的进行数据更新和删除操作。而针对需要对数据进行实时修改的OLTP
场景,ClickHouse
也提供了其他解决方案,如使用Kafka
和ZooKeeper
等技术实现数据的异步写入和更新。 -
ClickHouse
的数据写入是append-only
的方式,即只能新增数据,无法修改或删除已有数据。因此,在实际应用中,我们可以通过分区、TTL等技术来达到数据的删除和更新的效果。
ClickHouse
更为推荐的方式是通过异步写入和更新等技术,结合分区和TTL
等策略来实现数据的删除和更新操作
如何实现更新操作
ClickHouse
本身是一款列式存储数据库,为了提高性能,它采用了多版本控制(MVCC
)机制来支持数据的更新操作- 当我们对
ClickHouse
中的一条记录执行更新操作时,实际上会将原来的记录进行逻辑删除,并在其基础上创建一条新的记录。被逻辑删除的记录会在后续的合并操作(Merge
)中进行物理删除 - 由于
ClickHouse
的数据是以列的方式存储,所以在执行更新操作时,只需要修改需要更新的列即可,不会对其他列造成影响,避免了全表扫描的情况,从而提高了更新的效率 - 除了
MVCC
机制外,ClickHouse
还提供了一些类似于事务的机制,例如可以使用Transaction
引擎来将多个数据操作绑定在同一个事务中,保证数据一致性。同时,ClickHouse
还提供了Insert
、Alter
、Optimize
等操作来优化数据更新的效率和执行速度 - 虽然不建议使用,但是执行后也能起到效果,如果对实时性和准确性要求没那么高,也可以使用
- 实例如下,某张表增加某个字段,并设置一些值(当然,直接修改字段值也是这样
ALTER table ... update ... where ...
)
-- 新增字段
ALTER table radar.traffic_event add column `analysis_period` String comment '分析时段,早晚高峰';
-- 设置数据值
ALTER table radar.traffic_event update analysis_period = 'MORNING_RUSH_HOUR' where toHour(time_stamp) >= 7 and toHour(time_stamp) < 9 ;
ALTER table radar.traffic_event update analysis_period = 'PEEK_DAY_HOUR' where toHour(time_stamp) >= 9 and toHour(time_stamp) < 17 ;
ALTER table radar.traffic_event update analysis_period = 'EVENING_RUSH_HOUR' where toHour(time_stamp) >= 17 and toHour(time_stamp) < 19 ;
ALTER table radar.traffic_event update analysis_period = 'PEEK_NIGHT_HOUR' where analysis_period = '' ;
如何实现删除操作
ClickHouse
有3种方式实现数据的删除:
- 使用ALTER TABLE语句将表中的数据按照条件删除清空。
例如:下面两条语句,删除my_table
表所有记录,删除traffic_event
表字段approach
为空的记录
ALTER TABLE my_table DELETE WHERE 1=1
ALTER TABLE radar.traffic_event delete where approach = '';
- 使用
DROP PARTITION
语句删除指定Partition的数据(所以最好根据一定时间粒度建立分区)。
例如:此语句会删除my_table表中Partition
键为’202101’的分区数据
ALTER TABLE my_table DROP PARTITION '202101'
- 还有一种方式,在建表语句里设置
TTL
,或者修改表设置TTL
,则数据在一定时间后自动删除
-- 修改表的 TTL,time_stamp超过一定时间的数据自动删除
ALTER TABLE flow_stats MODIFY TTL time_stamp + toIntervalYear(5);
ALTER TABLE lane_status_in_phase MODIFY TTL time_stamp + toIntervalYear(3);
ALTER TABLE passing_vehicle MODIFY TTL time_stamp + toIntervalYear(3);
- 需要注意的是,
ClickHouse
的设计思想是用快照和分区来存储数据,因此数据删除操作实际上是逻辑删除,在ClickHouse
中数据的删除并不是物理删除,而是通过标记删除的方式使数据不再可用 - 如果对数据有真正的需求删除,可以将数据移动到归档表或备份中然后再进行删除
- 如果对删除后的数据不再关心,可以直接用
ALTER TABLE
语句清空表中的所有数据。
官方文档
clickhouse
官方文档很好,大家可以去看看,有中文版,大部分都翻译了- 关于
clickhouse
官网文档,关于alter
操作,可以点这里去查看