抱歉,您的瀏覽器無法訪問本站
本頁面需要瀏覽器支持(啟用)JavaScript
了解詳情 >

什么是ClickHouse

ClickHouse — open source distributed column-oriented DBMS

先来一句话:ClickHouse是一个用于OLAP场景的列式存储数据库管理系统。

什么是OLAP?

先来了解一下什么是OLAP,英文全称Online Analytical Processing,中文可以叫做:在线分析处理/联机分析,作用就是处理复杂的查询和数据分析。

OLAP系统通常用于数据挖掘和复杂的数据分析任务,例如预测分析、业务报告、数据仓库等。它可以处理大量的历史数据,并以多维度的方式展现数据,使用户能够从不同的角度和层次进行数据分析。

举个栗子,现在有家大型超市想要分析过去一年的营业数据,找到如下问题答案

  1. 哪些商品/品牌卖的最多
  2. 那个季度营业额最高
  3. 每天人流量/购买量如何

那么他就要对过去一年的数据进行多个维度的分析,而这就是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. 重复项相对于当前位置的偏移量
  2. 重复序列的长度
1
2
3
4
5
6
7
原文本:Hello, World! Hello, World!
LZ4压缩后:Hello, World! [12,13]
// 这里的12表示,从当前位置向前移动12位,13表示读取长度为13个字符的数据

原文本:ABCDEBCD
LZ4压缩后:ABCDE[4,3]
// 这里的4表示,从当前位置向前移动4位,3表示读取长度为3个字符的数据

我们为什么说列式存储有更好的压缩占比呢?

因为同一个列拥有相同的数据类型,同时在真实业务场景中列值也经常会重复,重复项越多,压缩比越高

基本使用

在了解ClickHouse的基本概念后,我们来看下怎么使用吧

前面提到了ClickHouse是一个数据库管理系统DBMS,因此他提供了相关的功能

  1. DDL数据定义语言,可以动态的创建/修改/删除数据库、表
  2. DML数据操作语言,可以动态的查询/新增/更改/删除数据
  3. 数据备份和恢复,可以对数据进行导出/导入等功能,保证线上环境数据安全

同时跟MySQL一样,可以使用标准的SQL语句来查询和管理ClickHouse的数据

安装clickhouse

1
2
3
4
5
6
7
8
// 拉取一下clickhouse的docker镜像
docker pull clickhouse/clickhouse-server

// 启动容器 指定容器名为test-clickhouse-server 文件限制数为262144
docker run -d --name test-clickhouse-server --ulimit nofile=262144:262144 clickhouse/clickhouse-server

// 使用clickhouse-client命令连接
docker exec -it test-clickhouse-server clickhouse-client

连接到服务器

  1. 使用ClickHouse的命令行客户端来连接
1
clickhouse-client --host localhost
  1. ClickHouuse同时还提供了HTTP客户端接口,支持直接发送HTTP请求来查询数据(当然正式环境应该是关闭的)

curl '<http://localhost:8123/?query=SELECT%201'1>

数据导入

假设我们现在有张test.test_table表,表结构如下

1
2
3
4
5
6
7
8
9
10
11
// 创建test库
CREATE DATABASE test
use test

CREATE TABLE test_table
(
id Int32,
name String,
value Float64
) ENGINE = MergeTree()
ORDER BY id;

传统方法INSERT

我们可以使用标准的SQL语句INSERT将数据导入,通常适合小型数据场景

1
INSERT INTO test_table(id,name,value) VALUES(1,‘Tom’,2.0)

同时也支持INSERT INTO … SELECT写法

1
2
3
4
5
// 例如从source_table中将value大于50的数据都导入进test_table中
INSERT INTO test_table (id, name, value)
SELECT id, name, value
FROM source_table
WHERE value > 50;

新方法NSERT INTO … FORMAT

我们可以使用客户端clickhouse-client命令行将文件数据导入表中

例如我们有一个CSV文件,名称为data.csv

1
2
3
4
5
1,John,100.0
2,Jane,200.0
3,Bob,300.0
// FORMAT参数指定导入类型为CSV,同时CSV文件的列顺序/类型都要和导入表匹配
clickhouse-client --query="INSERT INTO test_table FORMAT CSV" < data.csv

查/删/更改

查询语句同标准SQL并没有什么不一样,平常的使用就是各种聚合查询,同时表都是宽表,来避免需要JOIN联合查询

删和更改语句在clickhouse中一般是不执行的,OLAP场景中数据入库后通常是不发生更改的,不过clickhouse还是提供了DELETE和UPDATE语句,不过效率听说比较低下

参考资料