什么是ClickHouse
ClickHouse是一款开源列式数据源,由俄罗斯Yandex公司开发并开源(Yandex类似于中国的百度),这款开源数据库跑分远远高于目前市面上很多的商业数据库,比如Vertica。如果你没有听说过Vertica,那么你一定知道惠普,目前Vertica是惠普旗下的一款商业产品,Facebook的用户行为分析就是基于Vertica实现
什么是列式数据库
- 行数据库存储及检索数据过程
- 列数据库存储及检索数据过程
主要用于在线分析处理查询(OLAP),相对行式数据库,像Mysql、Oracle、SqlServer等都是行式存储,是把同一行的数据放到相邻同一数据块种,而列式存储是把同一列的数据放到相邻同一数据块种,这样在进行计算类查询时,可以大大减少IO,返回结果更快。
需要说明的是,ClickHouse不单单是一个数据库, 它是一个数据库管理系统。因为它允许在运行时创建表和数据库、加载数据和运行查询,而无需重新配置或重启服务
适用场景
- 大多数是读请求
- 数据总是以相当大的批(> 1000 rows)进行写入
- 不修改已添加的数据
- 每次查询都从数据库中读取大量的行,但是同时又仅需要少量的列
- 宽表,即每个表包含着大量的列
- 较少的查询(通常每台服务器每秒数百个查询或更少)
- 对于简单查询,允许延迟大约50毫秒
- 列中的数据相对较小: 数字和短字符串(例如,每个URL 60个字节)
- 处理单个查询时需要高吞吐量(每个服务器每秒高达数十亿行)
- 事务不是必须的
- 对数据一致性要求低
- 每一个查询除了一个大表外都很小
- 查询结果明显小于源数据,换句话说,数据被过滤或聚合后能够被盛放在单台服务器的内存中
优缺点
- 优点:
数据压缩
SQL语法支持
多核并行处理
支持近似计算
学习成本低 - 缺点
不支持事物
不支持Update操作,有限的Delete操作
支持有限操作系统
有限的SQL支持,join实现与众不同
不支持高并发
Clickhouse快是因为采用了并行处理机制,尽可能的压榨CPU,CPU使用率超过70%明显感觉到延时加长
数据类型
UInt8, UInt16, UInt32, UInt64, Int8, Int16, Int32, Int64
固定长度的整型,包括有符号整型或无符号整型。
无符号整型范围
UInt8 - [0 : 255]
UInt16 - [0 : 65535]
UInt32 - [0 : 4294967295]
UInt64 - [0 : 18446744073709551615]
Date
日期类型,用两个字节存储,表示从 1970-01-01 (无符号) 到当前的日期值。允许存储从 Unix 纪元开始到编译阶段定义的上限阈值常量(目前上限是2106年,但最终完全支持的年份为2105)。最小值输出为0000-00-00。
Decimal(P, S), Decimal32(S), Decimal64(S), Decimal128(S)
有符号的定点数,可在加、减和乘法运算过程中保持精度。对于除法,最低有效数字会被丢弃(不舍入)。
ps:由于现代CPU不支持128位数字,因此 Decimal128 上的操作由软件模拟。所以 Decimal128 的运算速度明显慢于 Decimal32/Decimal64。
String
字符串可以任意长度的。它可以包含任意的字节集,包含空字节。因此,字符串类型可以代替其他 DBMSs 中的 VARCHAR、BLOB、CLOB 等类型。
还有很多类型,就不一一列举了
表引擎
表引擎(即表的类型)决定了:
- 数据的存储方式和位置,写到哪里以及从哪里读取数据
- 支持哪些查询以及如何支持。
- 并发数据访问。
- 索引的使用(如果存在)。
- 是否可以执行多线程请求。
- 数据复制参数。
引擎种类:
- MergeTree 合并树
- Log
- Intergation engines 整合
- 其他特定功能的引擎
ClickHouse 最强大的引擎就是MergeTree引擎及该系列(*MergeTree)中的其他引擎。
适用于高负载任务的最通用和功能最强大的表引擎。这些引擎的共同特点是可以快速插入数据并进行后续的后台数据处理。 MergeTree系列引擎支持数据复制(使用Replicated的引擎版本),分区和一些其他引擎不支持的其他功能
该类型的引擎:
- MergeTree
- ReplacingMergeTree
- SummingMergeTree
- AggregatingMergeTree
- CollapsingMergeTree
- VersionedCollapsingMergeTree *
- GraphiteMergeTree
主要特点:
- 存储的数据按主键排序
- 允许使用分区
- 支持数据副本
- 支持数据采样
SQL语法
-
SELECT 语句用于执行数据的检索
语法:
SELECT [DISTINCT] expr_list
[FROM [db.]table | (subquery) | table_function] [FINAL]
[SAMPLE sample_coeff]
[ARRAY JOIN …]
[GLOBAL] ANY|ALL INNER|LEFT JOIN (subquery)|table USING columns_list
[PREWHERE expr]
[WHERE expr]
[GROUP BY expr_list] [WITH TOTALS]
[HAVING expr]
[ORDER BY expr_list]
[LIMIT n BY columns]
[LIMIT [n, ]m]
[UNION ALL …]
[INTO OUTFILE filename]
[FORMAT format]
说明:
a. USING中指定的列必须在两个子查询中具有相同的名称
b. 在各种类型的JOIN中,最高效的是ANY LEFT JOIN,然后是ANY INNER JOIN,效率最差的是ALL LEFT JOIN以及ALL INNER JOIN
c. 在所有情况下,不建议使用星号,因为它是列式数据库的缺点而不是优点 -
INSERT主要用于向系统中添加数据
语法:
INSERT INTO [db.]table [(c1, c2, c3)] VALUES (v11, v12, v13), (v21, v22, v23), …说明:
在进行INSERT时将会对写入的数据进行一些处理,按照主键排序,按照月份对数据进行分区等。所以如果在您的写入数据中包含多个月份的混合数据时,将会显著的降低INSERT的性能。为了避免这种情况:
a. 数据总是以尽量大的batch进行写入,如每次写入100,000行。
b. 数据在写入ClickHouse前预先的对数据进行分组。 -
CREATE DATABASE 用于根据指定名称创建数据库
语法:
CREATE DATABASE [IF NOT EXISTS] db_name -
CREATE TABLE 用于根据指定名称创建表结构
语法:
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
…
) ENGINE = engine -
旧版本不提供 SQL中delete删除单条数据或者条件删除,目前只支持按月删除数据分区
示例:
ALTER TABLE testdb.testtable DROP PARTITION ‘201907’clickhouse 另外提供了一个特殊的功能-设置TTL,TTL可以设置值的生命周期,它既可以为整张表设置,也可以为每个列字段单独设置。如果TTL同时作用于表和字段,clickhouse 会使用先到期的那个。被设置TTL的表,必须拥有Date 或 DateTime 类型的字段,要定义数据的生命周期,需要在这个日期字段上使用操作符
当clickhouse 发现数据过期时, 它将会执行一个计划外的合并。要控制这类合并的频率, 你可以设置 merge_with_ttl_timeout。如果该值被设置的太低, 它将导致执行许多的计划外合并,这可能会消耗大量资源。
如果在合并的时候执行SELECT 查询, 则可能会得到过期的数据。为了避免这种情况,可以在SELECT之前使用 OPTIMIZE 查询。18版本后提供删除和修改数据,且可以按照日删除
按日删除:ALTER TABLE testdb.testtable DROP PARTITION ‘20190701’
按条件删除:ALTER TABLE testdb.testtable DELETE WHERE NAME=‘111’
按条件修改:ALTER TABLE testdb.testtable UPDATE SET NAME=‘11’ WHERE NAME=‘111’ -
列字段 TTL
当列字段中的值过期时, ClickHouse会将它们替换成数据类型的默认值。
TTL子句不能被用于主键字段
示例说明:
创建一张包含 TTL 的表
CREATE TABLE example_table
(
d DateTime,
a Int TTL d + INTERVAL 1 MONTH,
b Int TTL d + INTERVAL 1 MONTH,
c String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d;已存在的列字段添加 TTL
ALTER TABLE example_table MODIFY COLUMN c String TTL d + INTERVAL 1 DAY;修改列字段的 TTL
ALTER TABLE example_table MODIFY COLUMN c String TTL d + INTERVAL 1 MONTH; -
行 TTL
当表内的数据过期时, ClickHouse会删除所有对应的行。
示例说明:
创建一张包含 TTL 的表
CREATE TABLE example_table
(
d DateTime,
a Int
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d
TTL d + INTERVAL 1 MONTH;修改列字段的 TTL
ALTER TABLE example_table MODIFY TTL d + INTERVAL 1 DAY;
好了,以上就是初步对clickhouse列式数据库有了一个简单的认识,在使用上,与传统的关系型数据库还是有一定的差别的,下面我们就开始实操了。