Clickhouse是一个用于联机分析处理(OLAP)的列式数据库管理系统(columnar DBMS)。
传统数据库在数据大小比较小,索引大小适合内存,数据缓存命中率足够高的情形下能正常提供服务。但残酷的是,这种理想情形最终会随着业务的增长走到尽头,查询会变得越来越慢。你可能通过增加更多的内存,订购更快的磁盘等等来解决问题(纵向扩展),但这只是拖延解决本质问题。如果你的需求是解决怎样快速查询出结果,那么ClickHouse也许可以解决你的问题。

应用场景:1.绝大多数请求都是用于读访问的2.数据需要以大批次(大于1000行)进行更新,而不是单行更新;或者根本没有更新操作3.数据只是添加到数据库,没有必要修改4.读取数据时,会从数据库中提取出大量的行,但只用到一小部分列5.表很“宽”,即表中包含大量的列6.查询频率相对较低(通常每台服务器每秒查询数百次或更少)7.对于简单查询,允许大约50毫秒的延迟8.列的值是比较小的数值和短字符串(例如,每个URL只有60个字节)9.在处理单个查询时需要高吞吐量(每台服务器每秒高达数十亿行)10.不需要事务11.数据一致性要求较低12.每次查询中只会查询一个大表。除了一个大表,其余都是小表13.查询结果显著小于数据源。即数据有过滤或聚合。返回结果不超过单个服务器内存大小

相应地,使用ClickHouse也有其本身的限制:

1.不支持真正的删除/更新支持 不支持事务(期待后续版本支持)2.不支持二级索引3.有限的SQL支持,join实现与众不同4.不支持窗口功能5.元数据管理需要人工干预维护


常用SQL语法


- 列出数据库列表show databases;-- 列出数据库中表列表show tables;-- 创建数据库create database test;-- 删除一个表drop table if exists test.t1;-- 创建第一个表create /*temporary*/ table /*if not exists*/ test.m1 (id UInt16,name String) ENGINE = Memory;-- 插入测试数据insert into test.m1 (id, name) values (1, 'abc'), (2, 'bbbb');-- 查询select * from test.m1;

默认值


默认值 的处理方面, ClickHouse 中,默认值总是有的,如果没有显示式指定的话,会按字段类型处理:

数字类型, 0
字符串,空字符串
数组,空数组
日期, 0000-00-00
时间, 0000-00-00 00:00:00
注:NULLs 是不支持的

数据类型


1.整型:UInt8,UInt16,UInt32,UInt64,Int8,Int16,Int32,Int64
范围U开头-2N/2~2N-1;非U开头0~2^N-12.枚举类型:Enum8,Enum16
Enum('hello'=1,'test'=-1),Enum是有符号的整型映射的,因此负数也是可以的3.字符串型:FixedString(N),String
N是最大字节数,不是字符长度,如果是UTF8字符串,那么就会占3个字节,GBK会占2字节;String可以用来替换VARCHAR,BLOB,CLOB等数据类型4.时间类型:Date5.数组类型:Array(T)
T是一个基本类型,包括arry在内,官方不建议使用多维数组6.元组:Tuple7.结构:Nested(name1 Type1,name2 Type2,...)
类似一种map的结

物化列


指定 MATERIALIZED 表达式,即将一个列作为物化列处理了,这意味着这个列的值不能从insert 语句获取,只能是自己计算出来的。同时,
物化列也不会出现在 select * 的结果中:

drop table if exists test.m2;create table test.m2 (a MATERIALIZED (b+1),b UInt16) ENGINE = Memory;insert into test.m2 (b) values (1);select * from test.m2;select a, b from test.m2;

表达式列


ALIAS 表达式列某方面跟物化列相同,就是它的值不能从 insert 语句获取。不同的是, 物化列 是会真正保存数据(这样查询时不需要再计算),
而表达式列不会保存数据(这样查询时总是需要计算),只是在查询时返回表达式的结果。

create table test.m3 (a ALIAS (b+1), b UInt16) ENGINE = Memory;insert into test.m3(b) values (1);select * from test.m3;select a, b from test.m3;

引擎/engine


引擎是clickhouse设计的精华部分

TinyLog


最简单的一种引擎,每一列保存为一个文件,里面的内容是压缩过的,不支持索引
这种引擎没有并发控制,所以,当你需要在读,又在写时,读会出错。并发写,内容都会坏掉。

应用场景:
a. 基本上就是那种只写一次
b. 然后就是只读的场景。
c. 不适用于处理量大的数据,官方推荐,使用这种引擎的表最多 100 万行的数据

drop table if exists test.tinylog;create table test.tinylog (a UInt16, b UInt16) ENGINE = TinyLog;insert into test.tinylog(a,b) values (7,13);

Log


这种引擎跟 TinyLog 基本一致
它的改进点,是加了一个 __marks.mrk 文件,里面记录了每个数据块的偏移
这样做的一个用处,就是可以准确地切分读的范围,从而使用并发读取成为可能
但是,它是不能支持并发写的,一个写操作会阻塞其它读写操作
Log 不支持索引,同时因为有一个 __marks.mrk 的冗余数据,所以在写入数据时,一旦出现问题,这个表就废了

应用场景:
同 TinyLog 差不多,它适用的场景也是那种写一次之后,后面就是只读的场景,临时数据用它保存也可以

drop table if exists test.log;create table test.log (a UInt16, b UInt16) ENGINE = Log;insert into test.log(a,b) values (7,13);

Memory


内存引擎,数据以未压缩的原始形式直接保存在内存当中,服务器重启数据就会消失
可以并行读,读写互斥锁的时间也非常短
不支持索引,简单查询下有非常非常高的性能表现

应用场景:
a. 进行测试
b. 在需要非常高的性能,同时数据量又不太大(上限大概 1 亿行)的场景

Merge


一个工具引擎,本身不保存数据,只用于把指定库中的指定多个表链在一起。
这样,读取操作可以并发执行,同时也可以利用原表的索引,但是,此引擎不支持写操作
指定引擎的同时,需要指定要链接的库及表,库名可以使用一个表达式,表名可以使用正则表达式指定

create table test.tinylog1 (id UInt16, name String) ENGINE=TinyLog;create table test.tinylog2 (id UInt16, name String) ENGINE=TinyLog;create table test.tinylog3 (id UInt16, name String) ENGINE=TinyLog;insert into test.tinylog1(id, name) values (1, 'tinylog1');insert into test.tinylog2(id, name) values (2, 'tinylog2');insert into test.tinylog3(id, name) values (3, 'tinylog3');use test;create table test.merge (id UInt16, name String) ENGINE=Merge(currentDatabase(), '^tinylog[0-9]+');select _table,* from test.merge order by id desc

Distributed


与 Merge 类似, Distributed 也是通过一个逻辑表,去访问各个物理表,设置引擎时的样子是:

Distributed(remote_group, database, table [, sharding_key])

Null


空引擎,写入的任何数据都会被忽略,读取的结果一定是空。

但是注意,虽然数据本身不会被存储,但是结构上的和数据格式上的约束还是跟普通表一样是存在的,同时,你也可以在这个引擎上创建视图

Buffer


1.Buffer 引擎,像是Memory 存储的一个上层应用似的(磁盘上也是没有相应目录的)2.它的行为是一个缓冲区,写入的数据先被放在缓冲区,达到一个阈值后,这些数据会自动被写到指定的另一个表中3.和Memory 一样,有很多的限制,比如没有索引4.Buffer 是接在其它表前面的一层,对它的读操作,也会自动应用到后面表,但是因为前面说到的限制的原因,一般我们读数据,就直接从源表读就好了,缓冲区的这点数据延迟,只要配置得当,影响不大的5.Buffer 后面也可以不接任何表,这样的话,当数据达到阈值,就会被丢弃掉

一些特点:

  • 如果一次写入的数据太大或太多,超过了 max 条件,则会直接写入源表。

  • 删源表或改源表的时候,建议 Buffer 表删了重建。

  • “友好重启”时, Buffer 数据会先落到源表,“暴力重启”, Buffer 表中的数据会丢失。

  • 即使使用了 Buffer ,多次的小数据写入,对比一次大数据写入,也 慢得多 (几千行与百万行的差距)

-- 创建源表create table test.mergetree (sdt  Date, id UInt16, name String, point UInt16) ENGINE=MergeTree(sdt, (id, name), 10);-- 创建 Buffer表-- Buffer(database, table, num_layers, min_time, max_time, min_rows, max_rows, min_bytes, max_bytes)create table test.mergetree_buffer as test.mergetree ENGINE=Buffer(test, mergetree, 16, 3, 20, 2, 10, 1, 10000);insert into test.mergetree (sdt, id, name, point) values ('2017-07-10', 1, 'a', 20);insert into test.mergetree_buffer (sdt, id, name, point) values ('2017-07-10', 1, 'b', 10);select * from test.mergetree;select '------';select * from test.mergetree_buffer;

Set


Set 这个引擎有点特殊,因为它只用在 IN 操作符右侧,你不能对它 select

create table test.set(id UInt16, name String) ENGINE=Set;insert into test.set(id, name) values (1, 'hello');-- select 1 where (1, 'hello') in test.set; -- 默认UInt8 需要手动进行类型转换select 1 where (toUInt16(1), 'hello') in test.set;

Join


TODO

MergeTree


这个引擎是 ClickHouse 的重头戏,它支持一个日期和一组主键的两层式索引,还可以实时更新数据。同时,索引的粒度可以自定义,外加直接支持采样功能

MergeTree(EventDate, (CounterID, EventDate), 8192)MergeTree(EventDate, intHash32(UserID), (CounterID, EventDate, intHash32(UserID)), 8192)

SummingMergeTree


1.SummingMergeTree 就是在 merge 阶段把数据sum求和2.sum求和的列可以指定,不可加的未指定列,会取一个最先出现的值

create table test.summingmergetree (sdt Date, name String, a UInt16, b UInt16) ENGINE=SummingMergeTree(sdt, (sdt, name), 8192, (a));insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-10', 'a', 1, 20);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-10', 'b', 2, 11);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-11', 'b', 3, 18);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-11', 'b', 3, 82);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-11', 'a', 3, 11);insert into test.summingmergetree (sdt, name, a, b) values ('2018-06-12', 'c', 1, 35);-- 手动触发一下 merge 行为optimize table test.summingmergetree;select * from test.summingmergetree;

AggregatingMergeTree


AggregatingMergeTree 是在 MergeTree 基础之上,针对聚合函数结果,作增量计算优化的一个设计,它会在 merge 时,针对主键预处理聚合的数据
应用于AggregatingMergeTree 上的聚合函数除了普通的 sum, uniq等,还有 sumState , uniqState ,及 sumMerge , uniqMerge 这两组

1.聚合数据的预计算
是一种“空间换时间”的权衡,并且是以减少维度为代价的

dim1 dim2 dim3 measure1
aaaa a 1 1
aaaa b 2 1
bbbb b 3 1
cccc b 2 1
cccc c 1 1
dddd c 2 1
dddd a 1 1

假设原始有三个维度,一个需要 count 的指标

dim1 dim2 dim3 measure1
aaaa a 1 1
aaaa b 2 1
bbbb b 3 1
cccc b 2 1
cccc c 1 1
dddd c 2 1
dddd a 1 1

通过减少一个维度的方式,来以 count 函数聚合一次 M

dim2 dim3 count(measure1)
a 1 3
b 2 2
b 3 1
c 1 1
c 2 1

2.聚合数据的增量计算

对于 AggregatingMergeTree 引擎的表,不能使用普通的 INSERT 去添加数据,可以用:a. INSERT SELECT 来插入数据b. 更常用的,是可以创建一个物化视图

drop table if exists test.aggregatingmergetree;create table test.aggregatingmergetree(sdt Date, dim1 String, dim2 String, dim3 String, measure1 UInt64) ENGINE=MergeTree(sdt, (sdt, dim1, dim2, dim3), 8192);-- 创建一个物化视图,使用 AggregatingMergeTreedrop table if exists test.aggregatingmergetree_view;create materialized view test.aggregatingmergetree_viewENGINE = AggregatingMergeTree(sdt,(dim2, dim3), 8192)asselect sdt,dim2, dim3, uniqState(dim1) as uvfrom test.aggregatingmergetreegroup by sdt,dim2, dim3;insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'aaaa', 'a', '10', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'aaaa', 'a', '10', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'aaaa', 'b', '20', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'bbbb', 'b', '30', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'cccc', 'b', '20', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'cccc', 'c', '10', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'dddd', 'c', '20', 1);insert into test.aggregatingmergetree (sdt, dim1, dim2, dim3, measure1) values ('2018-06-10', 'dddd', 'a', '10', 1);-- 按 dim2 和 dim3 聚合 count(measure1)select dim2, dim3, count(measure1) from test.aggregatingmergetree group by dim2, dim3;-- 按 dim2 聚合 UVselect dim2, uniq(dim1) from test.aggregatingmergetree group by dim2;-- 手动触发mergeOPTIMIZE TABLE test.aggregatingmergetree_view;select * from test.aggregatingmergetree_view;-- 查 dim2 的 uvselect dim2, uniqMerge(uv) from test.aggregatingmergetree_view group by dim2 order by dim2;

CollapsingMergeTree

是专门为 OLAP 场景下,一种“变通”存数做法而设计的,在数据是不能改,更不能删的前提下,通过“运算”的方式,去抹掉旧数据的影响,把旧数据“减”去即可,从而解决"最终状态"类的问题,比如 当前有多少人在线?

“以加代删”的增量存储方式,带来了聚合计算方便的好处,代价却是存储空间的翻倍,并且,对于只关心最新状态的场景,中间数据都是无用的

CollapsingMergeTree 在创建时与 MergeTree 基本一样,除了最后多了一个参数,需要指定 Sign 位(必须是 Int8 类型)

create table test.collapsingmergetree(sign Int8, sdt Date, name String, cnt UInt16) ENGINE=CollapsingMergeTree(sdt, (sdt, name), 8192, sign);

身边有些朋友面试找不到工作,我就干脆弄一个免费知识星球?,分享一下我平时看的技术文章,大家一起监督学习,共同进步

clickhouse物化视图优缺点_ClickHouse 适用场景相关推荐

  1. ClickHouse 物化视图在微信的实战

    前言 ClickHouse广泛用于用户和系统日志查询场景中,借助腾讯云提供基础设施,微信也在分阶段逐步推进clickhouse的建设和应用,目前作为基础建设的一部分,主要针对于OLAP场景,为业务方提 ...

  2. clickhouse 物化视图使用详解

    前言 视图这个概念大家并不陌生,在mysql中,视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据.作为一个select语句保存在数据字典中的.通过视图,可以展现基表(用来创建视图的表 ...

  3. ClickHouse 物化视图

    像通常的计算一样,强大的能力意味着至少有一点复杂性.这篇由两部分组成的文章通过准确解释物化视图的工作原理来填补空白,以便即使是初学者也可以有效地使用它们.我们将提供几个详细的示例,您可以根据自己的用途 ...

  4. Clickhouse物化视图详解

    文章目录 物化视图 1 概述 1.1 物化视图与普通视图的区别 1.2 优缺点 1.3 基本语法 1.4 创建物化视图的限制 1.5 物化视图的数据更新 2 案例实操 2.1 准备测试用表和数据 2. ...

  5. Clickhouse物化视图

    一.概念 clickhouse的物化视图是一种查询结果的持久化,给我们带来了查询效率的提升.用户查询效果和查表没有区别,其本质就是一张表,一张时刻在预计算的表,创建的过程用了一个特殊引擎: 注:使用c ...

  6. clickhouse 物化视图_再谈clickHouse:微博基于 ClickHouse 监控百亿流量下的指标

    一.前言 广告业务监控中,我们经常碰到多维度的数据储存和查询分析需求,比如,我们可能需要基于秒级粒度去统计某个接口 TP999 耗时,或者需要基于秒级粒度去统计微博广告在各个场景下的请求量,再或者我们 ...

  7. Clickhouse 物化视图 MATERIALIZED VIEW

    MATERIALIZED VIEW 物化视图物化视图支持表引擎,数据的保存形式由表的引擎决定.创建语法: CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db. ...

  8. 【Clickhouse】Clickhouse 物化视图 MATERIALIZED VIEW

    文章目录 1.概述 2.物化视图 2.案例 2.1 案例1 参考: 1.概述 2.物化视图 物化视图支持表引擎,数据的保存形式由表的引擎决定. 创建语法: CREATE [MATERIALIZED] ...

  9. 4万字长文ClickHouse应用实战-物化视图在微信的实践

    前言 ClickHouse广泛用于用户和系统日志查询场景中,借助腾讯云提供基础设施,微信也在分阶段逐步推进clickhouse的建设和应用,目前作为基础建设的一部分,主要针对于OLAP场景,为业务方提 ...

最新文章

  1. 盘点提高国内访问 GitHub 的速度的 9 种方案
  2. 语言准备客票问题_菲律宾出国留学需要准备什么?
  3. Eight puzzle --HOJ 11918
  4. html5调用系统声音1s响一次_记录一次系统性能调优过程
  5. android 监测bug上传到服务器,基于Android 错误信息捕获发送至服务器的详解
  6. switch注意事项与在什么情况下使用switch或if语句
  7. 求杨辉三角的前n行数据_两道简单的套公式算法题:杨辉三角
  8. 深入理解socket编程的几个函数和两种fd
  9. qq空间认证教程:借助企鹅媒体平台认证QQ公众空间
  10. 【语音增强】基于matlab GUI维纳滤波语音增强【含Matlab源码 298期】
  11. [Luogu] 被污染的河流
  12. 杭州仁和金融中心远程预付费电能管理系统的设计与应用-安科瑞耿敏花
  13. 详解Spring AOP原理
  14. Tomcat 中 tomcat9.exe 和 tomcat9w.exe 的使用
  15. js常用工具类(1)
  16. 双十一,一群金融大脑去了趟苏州!
  17. 解决电脑CPU占用率高问题
  18. 查看ip地址 通过域名
  19. C++学习笔记:fstream,ifstream和oftream的区别
  20. 常用IP地址端口对照表

热门文章

  1. 微信为什么不进入鸿蒙生态,马化腾为何迟迟不将微信, 加入任正非的华为鸿蒙生态系统中呢?...
  2. 小辣椒p60手机怎么样_小辣椒双机来临,搭载联发科 最低499元
  3. python序列化模块struct_python的struct模块
  4. ICCV 2017 EAST:《Learning Policies for Adaptive Tracking with Deep Feature Cascades》论文笔记
  5. r语言参数fig=c(),干货︱R语言绘图—基础图形参数整理
  6. linux脚本中怎么直接替换,linux-如何快速替换IP
  7. python国内书籍推荐_这些都是Python官方推荐的最好的书籍
  8. PHP基础3--文件加载-错误处理
  9. 【原创】面向对象作业:选课系统中用pickle储存多个对象间组合引用关系的那些坑...
  10. P2647 最大收益