clickhouse据说是用在大数据量的olap场景列式存储数据库,也有幸能够用到它在实际场景中落地。本篇就来说说简单的使用心得吧。
1. 整体说明
架构啥的,就不多说了,列式存储、大数据量、高性能。参见官方文档地址: https://clickhouse.com/docs/en/
对于使用者而言,除了泛泛而谈的架构之外,更多的是如何使用的问题。
从整体而言,clickhouse的使用方法基本遵守普通的sql规范,所以基本上只要你会写sql,对于普通的增删改查就问题不大了。也就是说应对业务而言,问题并不大了。
比如: create table...; select xx from t; insert into table xx... ; alter table xx update x=xx...;(当然了,这个用法差异有点大); alter table xx delete where x=xx...(同理);
2. 存储引擎简说
一个数据库的最大特点,应该就是其存储引擎或者说存储方式。而这在clickhouse体现得更加明显,其拥有超级多的存储引擎,不管你用不用得上,反正可选范围很大。
其中,我们最常用或者最简单可使用的是 MergeTree 系列,简单来说是归并树的存储结构,查询肯定是很快的,另外,它也适用于大数据量的存储。所以,一般就选择这玩意就行了。当然,它下面有很多的子类,需要根据作出相应的改变。
比如: ReplicatedMergeTree 代表有多节点存储数据,这对于高可用查询是必须的(针对任意节点的查询也是必须的)。
AggregatingMergeTree 代表当前节点是一种按主键聚合的数据分片方式。
单就MergeTree引擎而言,如果想要有比较优化的应用或者比较特殊的需求,则必须要亲自再去细细翻阅clickhouse的官方文档了,太多选择是真苦恼啊。
其他存储引擎,比如 Log系列,则更少场景会使用到,一般当作临时表用时,可以考虑。其他的如 File, 则可以算是被当作解析器来使用。。。
总之,要全面理解ck的存储引擎,实非易事,除非深度使用它。
3. clickhouse中的主键
clickhouse中,其实并没有明确说一定要有主键之类的话,只是在创建表时,会默认以排序字段作为主键。
它的主键的作用,一定程度上相当于普通索引,这可能也是为什么它没有明确叫主键的原因,因为不需要唯一但有利于查找。
但它还是有 Primary Key 的定义。
4. curd sql
我们只说最简单的方式,但其实clickhouse中,有一个非常大的特点就是,它的sql非常之多样,灵活,不管你用不用得上,反正就是功能很多。而且文档也是呵呵的。
-- 创建表, 值得说明的是,它可以非常复杂的过期策略 CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ( name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr1] [compression_codec] [TTL expr1], name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|ALIAS expr2] [compression_codec] [TTL expr2], PRIMARY KEY(expr1[, expr2,...])], ... ) ENGINE = MergeTree comment 'xxx' PARTITION BY toYYYYMM(d) TTL d + INTERVAL 1 MONTH [DELETE], d + INTERVAL 1 WEEK TO VOLUME 'aaa', d + INTERVAL 2 WEEK TO DISK 'bbb'; -- 更新和删除,这语法够独特的,据说是为了让大家少用这种功能而设计的,厉害了 ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE WHERE filter_expr -- 查询,有很多独特的用法,如WITH [WITH expr_list|(subquery)] SELECT [DISTINCT [ON (column1, column2, ...)]] expr_list [FROM [db.]table | (subquery) | table_function] [FINAL] [SAMPLE sample_coeff] [ARRAY JOIN ...] [GLOBAL] [ANY|ALL|ASOF] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER|SEMI|ANTI] JOIN (subquery)|table (ON <expr_list>)|(USING <column_list>) [PREWHERE expr] [WHERE expr] [GROUP BY expr_list] [WITH ROLLUP|WITH CUBE] [WITH TOTALS] [HAVING expr] [ORDER BY expr_list] [WITH FILL] [FROM expr] [TO expr] [STEP expr] [LIMIT [offset_value, ]n BY columns] [LIMIT [n, ]m] [WITH TIES] [SETTINGS ...] [UNION ...] [INTO OUTFILE filename [COMPRESSION type] ] [FORMAT format] -- 数据插入,可以作排除性插入语法 INSERT INTO [db.]table [(c1, c2, c3)] VALUES (v11, v12, v13), (v21, v22, v23), ... INSERT INTO [db.]table [(c1, c2, c3)] SELECT ... INSERT INTO insert_select_testtable (* EXCEPT(b)) Values (2, 2); -- 执行计划查询,这对于了解其内部机制很有帮助,它的执行计划非常详细,不过看起来也有点吓人 EXPLAIN [AST | SYNTAX | PLAN | PIPELINE] [setting = value, ...] SELECT ... [FORMAT ...]