本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!
在上一篇文章中,我们了解了ClickHouse
的适用场景以及为什么那么快
在这篇文章中我们就可以开始上手操作了
安装
先来安装一个ClickHouse
服务
这里我选择直接使用Docker
的方式来部署
- 拉取镜像
shell
docker pull yandex/clickhouse-server
- 运行容器
shell
docker run -d -p 8123:8123 -p 9000:9000 --name clickhouse yandex/clickhouse-server
由于本系列只是带大家熟悉ClickHouse
的基本概念与操作
所以直接使用最简单的方式来安装ClickHouse
便于我们动手实践
不过不建议使用该方式部署正式环境
建表
之前说过ClickHouse
是兼容标准SQL
的
那就用我们熟知的建表语句先创建一张表吧
数据类型
不过在建表之前,需要先了解ClickHouse
中有哪些数据类型
平时在MySQL
中用的比较多的数据类型也就是整型,字符串和时间
我们现在看看在ClickHouse
中的整型,字符串和时间都叫什么
(实际上ClickHouse
还有很多其他的基础类型和复合类型,如数组,元组,嵌套类型等,在这里就先不展开了)
- 整型
在ClickHouse
中整型可以使用Int8
,Int16
,Int32
,Int64
来表示
相比于MySQL
中使用tinyint
,smallint
,mediumint
,int
,bigint
这种通过"小","中","大"来描述大小的定义
我倒是觉得直接用"8","16","32","64"来的更直观一点
- 字符串
字符串直接用String
即可
也不需要像MySQL
中的varcher
需要指定大小
不过也存在FixedString
用于定长字符串
- 时间
ClickHouse
中也提供了和MySQL
中datetime
类似的DateTime
类型来表示时间
建表DDL
在大概了解了ClickHouse
的数据类型之后
如下就是我们的建表语句了
sql
create table test
(
id Int64,
name String,
create_time DateTime
)
当我自信万分的执行了这句脚本之后
噔!只见一行红色的报错出现在了我的控制台
console
Code: 62. DB::Exception: Syntax error: failed at position 80 (end of query) (line 6, col 2): . Expected one of: storage definition, ENGINE, AS. (SYNTAX_ERROR) (version 22.1.3.7 (official build))
可恶!没想到竟然开局失利
不过不用在意,这样的事情对我来说已经是家常便饭了
让我们 ChatGPT Google Baidu 看看这又是整什么幺蛾子
搜跌死捏,我已经完全明白了
ClickHouse
在建表的时候需要指定表引擎,也就是ENGINE
大家可以理解为类似MySQL
中的引擎
不同的表引擎会有不同的特性,适合不同的场景
表引擎
ClickHouse
有非常多的表引擎可供我们选择
为了不让对表引擎不太熟悉的选择困难症们纠结到底使用哪一个
我们直接使用MergeTree
这个最常用的系列
于是,我们的建表SQL
就变成了这样
sql
create table test
(
id Int64,
name String,
create_time DateTime
) ENGINE = MergeTree();
排序键和主键
你以为这样就能建表成功了吗?太天真了!
大家有没有发现我们的建表语句里面竟然没有指定主键
虽然MySQL
可以不设置主键(因为会有一个全局的ID)
但是我们平时建表的时候肯定都会指定主键
有了主键索引就能更快的查询数据
所以对于ClickHouse
的MergeTree
引擎来说
必须指定ORDER BY
参数,也就是排序键
sql
create table test
(
id Int64,
name String,
create_time DateTime
) ENGINE = MergeTree()
order by id;
这样就没有问题了
哎~为什么是排序键而不是主键呢?
其实是因为ClickHouse
会默认使用指定的排序键作为主键
不过你也可以手动指定主键
java
create table test
(
id Int64,
name String,
create_time DateTime
) ENGINE = MergeTree()
primary key id
order by (id, name);
这样就是使用id
作为主键同时对数据进行先id
后name
的排序了
不过需要注意的是手动指定的主键必须是排序键的开头的字段
比如下面这样是不行的
sql
create table test
(
id Int64,
name String,
create_time DateTime
) ENGINE = MergeTree()
primary key name
order by (id, name);
先通过id
排序在通过name
排序,但是使用name
作为主键就会提示异常
console
Primary key must be a prefix of the sorting key, but the column in the position 0 is id, not name.
就是说排序键的第一个字段是id
不是name
,所以主键必须要从id
开始
这个其实就和我们平时所说的索引的最左前缀匹配原则是一样的
插入数据
我们的表算是创建成功了
接下来就要开始插入数据了
浅浅尝试一条,万一和建表一样全是坑
sql
insert into test(id, name, create_time) VALUES (1, '1', '2024-03-16');
Lucky!插入成功了
SELECT子句
除了这种常用的插入方式
ClickHouse
还支持通过select
子句来批量插入
我们现在有一张另外的表test_source
id | first_name | last_name |
---|---|---|
1 | first1 | last1 |
2 | first2 | last2 |
3 | first3 | last3 |
假设我们需要将test_source
中的数据进行一些处理之后插入到test
表中
其中id
直接移过去,name
需要用first_name
+last_name
,时间需要当前时间
我们可以这样来导入
sql
insert into test(id, name, create_time) select id, concat(first_name, last_name) as name, now() from test_source;
炒鸡方便有木有
我们不需要用程序把数据查询出来计算完后再批量导入
而只需要一句SQL
就可以完成所有操作
不过这里也需要注意
如果数据量过大的话可能会导致ClickHouse
的内存达到上限(可以通过配置修改上限)
所以一般大数据量是通过分批导入的
更新删除数据
我们再来试试更新和删除操作
sql
update test set name = 'name1' where id = 1
delete from test where id = 1;
和我们平时的更新和删除一样
执行也完全没有问题
西卡西!
不要觉得没问题就肆无忌惮的更新和删除哦
这两句SQL
的本来面目其实是这样的
sql
alter table test update name = 'name1' where id = 1;
alter table test delete where id = 1;
虽然我们可以成功的执行更新和删除
但是这种操作的成本是很高的
只是我们看着只是修改了一个字段而已
而且整个操作是异步的哦
也就是说更新和删除之后可能并不会马上生效
总结
ClickHouse
在建表的时候需要指定引擎用于适配不同的业务场景
ClickHouse
能够通过Select
自查询来批量导入数据
ClickHouse
的MergeTree
引擎要避免频繁的使用更新和删除操作