clickhouse基本概念

[TOC]

优点

  1. 底层支持数据的列式存储,支持压缩, 优化数据存储,优化索引数据 优化底层存储

缺点

  1. 不支持事务,不支持真正的删除、更新
  2. 不支持高并发
  3. 不支持二级索引
  4. 不擅长多表 join,大宽表
  5. 元数据管理需要人为干预
  6. 尽量做 1000条以上批量的写入,避免逐行insert或者 小批量的 insert,update,delete

clickhouse 安装

1
2
3
4
5
6
7
8
# 单节点安装
 docker pull yandex/clickhouse-server
# 开启容器
docker run -d --name clickhouse-test-server --ulimit nofile=262144:262144 --volume=/Users/lixin/DockerWorkspace/clickhouse/clickhouse-test-db:/var/lib/clickhouse yandex/clickhouse-server
# 进入容器
docker exec -it clickhouse-test-server /bin/bash

 

sql命令

练习网站

1
2
3
4
5
6
show tables
# 查看行数
select count(1) from hists_v1


select * from hits_v1;

建表语法

1
2
3
4
5
6
7
8
9
create table tb_demo01 (
	id UInt16,
    name String,
    age UInt8,
    birthday Date,
    gender Fixedstring(2)
    
)
engine=Log

这个 engine 不一样,决定了底层存储的文件不一样

1
2
3
4
5
6
7
create table  tb_data_type_val(
	id Int16,
    age UInt8,
    sal Float32,
    colmm Float64,
    money Decimal(7,2)
)

数组类型

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
select array(1,2,3,4) as list;
select [1,2,3] as list,toTypeName(list);


-- 

create table tb_data_arr_test(
	id UInt8	  comment '用户ID'  ,	
    fs Array(String)  comment '用户的朋友列表'
)ENGINE= Memory;

INSERT INTO t_friend values(1,array(1,2,3))
1
2
3
4
select range(6),range(1,5),range(1,6,2)

-- 数组中的高阶函数
select id,name ,arrayMap(e->upper(e),fs) from t_friend;

nested 类型

参考文档

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
create table t_nested
(
 id Int16,
 name String,
 properties Nested (
 	pid UInt32,
    k String,
    v String
 )

);
CREATE TABLE test.visits
(
    CounterID UInt32,
    StartDate Date,
    Sign Int8,
    IsNew UInt8,
    VisitID UInt64,
    UserID UInt64,
    ...
    Goals Nested
    (
        ID UInt32,
        Serial UInt32,
        EventTime DateTime,
        Price Int64,
        OrderID String,
        CurrencyID UInt32
    ),
    ...
) ENGINE = CollapsingMergeTree(StartDate, intHash32(UserID), (CounterID, StartDate, intHash32(UserID), VisitID), 8192, Sign)
1
2
3
4
5
6
SELECT
    Goals.ID,
    Goals.EventTime
FROM test.visits
WHERE CounterID = 101500 AND length(Goals.ID) < 5
LIMIT 10

tuple 类型

1
2
3
4
create table named_tuples( `a` Tuple(s String ,i Int64)) ENGINE= memory;

insert into named_tuples values ((y,10),('x',-10))
-- 查询 a.x 和 a.i

窗口函数的概念

窗口函数(Window Function) 是 SQL2003 标准中定义的一项新特性,并在 SQL2011、SQL2016 中又加以完善,添加了若干处拓展。窗口函数不同于我们熟悉的普通函数和聚合函数,它为每行数据进行一次计算:输入多行(一个窗口)、返回一个值。在报表等分析型查询中,窗口函数能优雅地表达某些需求,发挥不可替代的作用。

本文首先介绍窗口函数的定义及基本语法,之后将介绍在 DBMS 和大数据系统中是如何实现高效计算窗口函数的,包括窗口函数的优化、执行以及并行执行。

窗口函数出现在 SELECT 子句的表达式列表中,它最显著的特点就是 OVER 关键字。语法定义如下

  • PARTITION BY 表示将数据先按 part_list 进行分区
  • ORDER BY 表示将各个分区内的数据按 order_list 进行排序

https://segmentfault.com/img/bVcSm8m

最后一项表示 Frame 的定义,即:当前窗口包含哪些数据?

  • ROWS 选择前后几行,例如 ROWS BETWEEN 3 PRECEDING AND 3 FOLLOWING 表示往前 3 行到往后 3 行,一共 7 行数据(或小于 7 行,如果碰到了边界)
  • RANGE 选择数据范围,例如 RANGE BETWEEN 3 PRECEDING AND 3 FOLLOWING 表示所有值在 c−3,c+3 这个范围内的行,cc 为当前行的值

现代 DBMS 大多支持并行执行。对于窗口函数,由于各个分区之间的计算完全不相关,我们可以很容易地将各个分区分派给不同的节点(线程),从而达到分区间并行

但是,如果窗口函数只有一个全局分区(无 PARTITION BY 子句),或者分区数量很少、不足以充分并行时,怎么办呢?上文中我们提到的 Removable Aggregator 的技术显然无法继续使用了,它依赖于单个 Aggregator 的内部状态,很难有效地并行起来。

TUM 的这篇论文中提出使用线段树(Segment Tree)实现高效的分区内并行。线段树是一个 N 叉树数据结构,每个节点包含当前节点下的部分聚合结果。

下图是一个使用二叉线段树计算 SUM() 的例子。例如下图中第三行的 1212,表示叶节点 5+75+7 的聚合结果;而它上方的 2525 表示叶节点 5+7+3+105+7+3+10 的聚合结果。

clickhouse 如何将 mysql 进行数据迁移