什么是ClickHouse
先来一句话:ClickHouse是一个用于OLAP场景的列式存储数据库管理系统。
什么是OLAP?
先来了解一下什么是OLAP,英文全称Online Analytical Processing,中文可以叫做:在线分析处理/联机分析,作用就是处理复杂的查询和数据分析。
OLAP系统通常用于数据挖掘和复杂的数据分析任务,例如预测分析、业务报告、数据仓库等。它可以处理大量的历史数据,并以多维度的方式展现数据,使用户能够从不同的角度和层次进行数据分析。
举个栗子,现在有家大型超市想要分析过去一年的营业数据,找到如下问题答案
- 哪些商品/品牌卖的最多
- 那个季度营业额最高
- 每天人流量/购买量如何
那么他就要对过去一年的数据进行多个维度的分析,而这就是OLAP系统所擅长的,将数据从商品/品牌/季度/人流量进行切块分析,获得想要的结果。
OLAP系统的价值和作用一句话总结就是:从大量的数据中提取用户感兴趣或者有价值的信息,来帮助用户更好来决策。
列式存储
这里的列式存储是什么意思呢?我们平常使用的MySQL是传统的行式存储数据库,即每行的数据是物理上存储在一起的。
ID | Name | Age |
---|---|---|
1 | Alice | 20 |
2 | Bob | 25 |
3 | Charlie | 30 |
行式存储会按照下面的方式存储这些数据:
1 | 1, Alice, 202, Bob, 253, Charlie, 30 |
行式存储的好处在于针对单个记录的查询/写入/事务操作,因为记录的数据都存储在一起,可以一次性读取或者写入。
1 | 1, 2, 3Alice, Bob, Charlie20, 25, 30 |
列式存储的好处在于处理大量数据的聚合查询,只需要读取相关的列即可,无关的列数据无需读取,同时相同的类型存储物理上存储在一起,更方便数据压缩,因此特别适合于OLAP场景。
我认为ClickHouse最明显的两个标签就是OLAP和Column-based列式存储
ClickHouse为什么这么快
当有人问ClickHouse为什么这么快,我们可以回答
- 基于列式存储:OLAP场景中通常都是宽表,而实际使用中通常只需要其中的几个列,基于列式存储可以避免不必要的磁盘读取操作。
- 基于同种类型的数据压缩:由于是列式存储,因此可以更好的将相同类型的数据进行压缩,同时ClickHouse还提供了专门的编解码器,提高压缩比。
- 基于细节优化:ClickHouse基于具体场景来使用更符合的数据结构和算法
- 基于索引优化:ClickHouse为每张表都自动创建了主键索引,还提供了数据跳过索引、分区键等功能
这是官方关于介绍ClickHouse为什么这么快文档:https://clickhouse.com/docs/zh/faq/general/why-clickhouse-is-so-fast
压缩算法
压缩算法是一种常见的用时间换空间的算法,用于减少数据存储空间或者网络传输时间。本质上就是通过找出冗余信息/重复项,然后使用更短的方式去表示,来实现减少数据占用空间。
在ClickHouse中默认使用的是LZ4压缩算法,这是一种无损压缩算法,特点是压缩速度快,解压速度更快。简单来说LZ4会先扫描要压缩的文本,然后找出重复项,随后写下两个信息
- 重复项相对于当前位置的偏移量
- 重复序列的长度
1 | 原文本:Hello, World! Hello, World! |
我们为什么说列式存储有更好的压缩占比呢?
因为同一个列拥有相同的数据类型,同时在真实业务场景中列值也经常会重复,重复项越多,压缩比越高
基本使用
在了解ClickHouse的基本概念后,我们来看下怎么使用吧
前面提到了ClickHouse是一个数据库管理系统DBMS,因此他提供了相关的功能
- DDL数据定义语言,可以动态的创建/修改/删除数据库、表
- DML数据操作语言,可以动态的查询/新增/更改/删除数据
- 数据备份和恢复,可以对数据进行导出/导入等功能,保证线上环境数据安全
同时跟MySQL一样,可以使用标准的SQL语句来查询和管理ClickHouse的数据
安装clickhouse
1 | // 拉取一下clickhouse的docker镜像 |
连接到服务器
- 使用ClickHouse的命令行客户端来连接
1 | clickhouse-client --host localhost |
- ClickHouuse同时还提供了HTTP客户端接口,支持直接发送HTTP请求来查询数据(当然正式环境应该是关闭的)
curl '<http://localhost:8123/?query=SELECT%201'1
>
数据导入
假设我们现在有张test.test_table表,表结构如下
1 | // 创建test库 |
传统方法INSERT
我们可以使用标准的SQL语句INSERT将数据导入,通常适合小型数据场景
1 | INSERT INTO test_table(id,name,value) VALUES(1,‘Tom’,2.0) |
同时也支持INSERT INTO … SELECT写法
1 | // 例如从source_table中将value大于50的数据都导入进test_table中 |
新方法NSERT INTO … FORMAT
我们可以使用客户端clickhouse-client命令行将文件数据导入表中
例如我们有一个CSV文件,名称为data.csv
1 | 1,John,100.0 |
查/删/更改
查询语句同标准SQL并没有什么不一样,平常的使用就是各种聚合查询,同时表都是宽表,来避免需要JOIN联合查询
删和更改语句在clickhouse中一般是不执行的,OLAP场景中数据入库后通常是不发生更改的,不过clickhouse还是提供了DELETE和UPDATE语句,不过效率听说比较低下