ClickHouse的原理及使用,

1、前言

一款MPP查询分析型数据库——ClickHouse。它是一个开源的,面向列的分析数据库,由Yandex为OLAP和大数据用例创建。ClickHouse对实时查询处理的支持使其适用于需要亚秒级分析结果的应用程序。ClickHouse的查询语言是SQL的一种方言,它支持强大的声明性查询功能,同时为最终用户提供熟悉度和较小的学习曲线。

它可以替代Elasticserach做深度聚合需求,性能表现不错,在数据量千万级亿级表现很好,且资源消耗相比之前降低不少,同样的服务器资源可以承担更多的业务需求。

2、ClickHouse 概述

1.1 什么是ClickHouse

ClickHouse 是俄罗斯的 Yandex 于2016年开源的列式存储数据库(DBMS),主要用于在线分析处理查询(OLAP),能够使用SQL 查询实时生成分析数据报告。

1.2 什么是列式存储

以下面的表为例:

IdNameAge
1张三18
2李四22
3王五34

采用行式存储时,数据在磁盘上的组织结构为:

好处是想查某个人所有的属性时,可以通过一次磁盘查找加顺序读取就可以。但是当想查所有人的年龄时,需要不停的查找,或者全表扫描才行,遍历的很多数据都是不需要的。

而采用列式存储时,数据在磁盘上的组织结构为:

这时想查所有人的年龄只需把年龄那一列拿出来就可以了。

1.3 安装前的准备

1.3.1 CentOS 取消打开文件数限制

在/etc/security/limits.conf、 /etc/security/limits.d/90-nproc.conf 这2个文件的末尾加入一下内容:

vi /etc/security/limits.conf
在文件末尾添加:
* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072vi /etc/security/limits.d/90-nproc.conf
在文件末尾添加:
* soft nofile 65536
* hard nofile 65536
* soft nproc 131072
* hard nproc 131072

重启服务器之后生效,用ulimit -n 或者 ulimit -a 查看设置结果

ulimit -n

1.3.2 CentOS 取消SELINUX

SELINUX 是 CentOS 类似于windows 下的安全360,修改 /etc/selinux/config 中的 SELINUX=disabled 后重启

vi /etc/selinux/config
SELINUX=disabled

1.3.3 关闭防火墙

service iptables stop
service ip6tables stop

1.3.4 安装依赖

yum install -y libtool
yum install -y *unixODBC*
yum search libicu
yum install libicu.x86_64

2、安装

2.1 网址

官网:https://clickhouse.yandex/

下载地址:http://repo.red-soft.biz/repos/clickhouse/stable/el7/

2.2 单机模式

上传5个文件到 mkdir /usr/local/clickhouse

clickhouse-client-1.1.54236-4.el7.x86_64.rpm    09-Jun-2017 11:02   3.0K     
clickhouse-compressor-1.1.54236-4.el7.x86_64.rpm    09-Jun-2017 11:02   880K     
clickhouse-debuginfo-1.1.54236-4.el7.x86_64.rpm 09-Jun-2017 11:02   8.6M     
clickhouse-server-1.1.54236-4.el7.x86_64.rpm    09-Jun-2017 11:02   32M  
clickhouse-server-common-1.1.54236-4.el7.x86_64.rpm 09-Jun-2017 11:02   8.0K

2.2.2 分别安装这5个rpm 文件

rpm -ivh /usr/local/clickhouse/*.rpm

2.2.3 启动 ClickServer

前台启动:

clickhouse-server --config-file=/etc/clickhouse-server/config.xml

查看启动后的进程:ps -aux | grep click

后台启动:

nohup clickhouse-server --config-file=/etc/clickhouse-server/config.xml >null 2>&1 &

2.2.4 使用 client 连接server

clickhouse-client

2.3 分布式集群安装

2.3.1 在node-02、node-03 上面执行之前的所有步骤

2.3.2 三台机器修改配置文件 vi /etc/clickhouse-server/config.xml

<listen_host>0.0.0.0</listen_host><!-- <listen_host>::1</listen_host> --><!-- <listen_host>127.0.0.1</listen_host> -->

将刚刚修改好的配置分发到三台机器上去: ync.sh /etc/clickhouse-server/config.xml

2.3.3 在三台机器的etc 目录下新建 metrika.xml 文件

vi /etc/metrika.xml
添加如下内容:

<yandex>
<clickhouse_remote_servers>
<perftest_3shards_1replicas>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>node-01</host>
<port>9000</port>
</replica>
</shard>
<shard>
<replica>
<internal_replication>true</internal_replication>
<host>node-02</host>
<port>9000</port>
</replica>
</shard>
<shard>
<internal_replication>true</internal_replication>
<replica>
<host>node-03</host>
<port>9000</port>
</replica>
</shard>
</perftest_3shards_1replicas>
</clickhouse_remote_servers><!--zookeeper相关配置-->
<zookeeper-servers>
<node index="1">
<host>node-01</host>
<port>2181</port>
</node>
<node index="2">
<host>node-02</host>
<port>2181</port>
</node>
<node index="3">
<host>node-03</host>
<port>2181</port>
</node>
</zookeeper-servers><macros>
<replica>node-01</replica>
</macros><networks>
<ip>::/0</ip>
</networks><clickhouse_compression>
<case>
<min_part_size>10000000000</min_part_size>
<min_part_size_ratio>0.01</min_part_size_ratio>
<method>lz4</method>
</case>
</clickhouse_compression></yandex>

注意:下面标红的地方需要根据机器不同去修改,node-02就是修改成node-02, node-03就是修改成node-03

node-01

3.3.4 三台机器启 ClickServer

首先在三台机器开启Zookeeper

前台启动:

clickhouse-server --config-file=/etc/clickhouse-server/config.xml

查看启动后的进程:ps -aux | grep click

后台启动:

nohup clickhouse-server --config-file=/etc/clickhouse-server/config.xml >null 2>&1 &

集群搭建成功,进入clickhouse-client 客户端:

这里补充ClickHouse与Elasticsearch一样,都采用列式存储结构,都支持副本分片,不同的是ClickHouse底层有一些独特的实现,如下:

  • MergeTree 合并树表引擎,提供了数据分区、一级索引、二级索引。
  • Vector Engine 向量引擎,数据不仅仅按列存储,同时还按向量(列的一部分)进行处理,这样可以更加高效地使用CPU。

3、数据类型

3.1 整型

固定长度的整型,包括有符号整型或无符号整型。Clickhouse 对大小写敏感。整型范围(-2^(n-1) ~ 2^(n-1) - 1):

Int8 −128:127
Int16 −32768:32767
Int32 −2147483648:2147483647
Int64 −9223372036854775808:9223372036854775807

无符号整型范围(0 ~ 2^n -1)

UInt8 0:255
UInt16 0:65535
UInt32 0:4294967295
UInt64 0:18446744073709551615

3.2 浮点型

Float32 - float
Float64 - double

建议尽可能以整型形式存储数据。例如,将固定精度的数字转换为整数值,如果间用毫秒为单位表示,因为浮点型进行计算时可能引起四舍五入的误差,比如1-0.9。

与标准SQL 相比,ClickHouse 支持以下类别的浮点数:Inf - 正无穷  1/0-Inf - 负无穷 NaN - 非数字:

3.3 布尔型

没有单独的类型来存储布尔值。可以使用 UInt8 类型,取值限制为 0 或 1 。

3.4 字符串

1)String

字符串可以任意长度的。它可以包含任意的字节集,包含空字节。

2) FixedString(N)

固定长度N 的字符串,N 必须是严格的正自然数。当服务端读取长度小于N的字符串时候,通过在字符串末尾添加空字节来达到N 字节长度。当服务端读取长度大于 N 的字符串时候,将返回错误消息。与String 相比,极少会使用FixedString,因为使用起来不是很方便。

3.5 枚举类型

ClickHouse 支持枚举类型,这是一种在定义常量时经常会使用的数据类型。ClickHouse 提供了Enum8 和Enum16 两种枚举类型,它们除了取值范围不同之外,别无二致。枚举固定使用(String:Int)Key/Value 键值对的形式定义数据,所以Enum8 和Enum16分别会对应(String:Int8)和(String:Int16)

用法演示:

create table enum(enum Enum8('hello'=0, 'enum'=1))engine=TinyLog
-- 枚举数据类型
CREATE TABLE test_enum(id Int8, color Enum8('red'=1, 'green'=2, 'blue'=3)) engine=Memory;
insert into test_enum values(1,'red'),(2,'red'),(3,'green');
-- 也可以使用这种方式进行插入数据:
insert into test_enum values(4,3);
insert into test_enum values(5,'pink'); -- 没有声明的值是不能插入select id, toInt32(color) from test_enum;
-- 节省存储空间,提升处理效率;底层存储Int类型,占用空间最小

3.6 数组

Array(T):由T 类型元素组成的数组。T 可以是任意类型,包含数组类型。但不推荐使用多维数组,ClickHouse 对多维数组的支持有限。例如,不能在MergeTree 表中存储多维数组。可以使用 array 函数来创建数组:array(T)也可以使用方括号:[]   -- 数组数据类型array(T) 数组是强数据类型e1,e2,d3...   toTypeName() -- 查看变量的数据类型

CREATE TABLE test_array
(name String, hobby Array(String)
) ENGINE = Loginsert into test_array values
('张三',['读书','爬山','散步']),
('李四',['read','hiking','dance']),
('王五',array('吃','睡','喝','玩'));select * from test_array;insert into test_array values ('张三2',['读书','爬山','散步']);
insert into test_array values ('李四2',['read','hiking','dance']);
insert into test_array values ('王五2',array('吃','睡','喝','玩'));-- clickhouse 会利用多核处理器将数据分块存储、计算
select * from test_array;-- 查询数组中的数据
select *, hobby[1] from test_array;-- 遍历数组中每个元素,给每个元素加上'abc'
select arrayMap(e -> concat(e, 'abc'), hobby) from test_array;

3.7 Tupe 元组

是一个特殊的数据类型,集合
可以存储任意的数据类型,在定义的时候声明数据类型和数据元素个数
元组类型由1~n 个元素组成,每个元素之间允许设置不同的数据类型,且彼此之间不要求兼容。无组同样支持类型推断,
其推断依据仍然以最小存储代码为原则。与数组类似,元组也可以使用两种方式定义

常规方式tuple(T):元组中可以存储多种数据类型,但是要注意数据类型的顺序
Tuple(String, UInt8, Date)

select tuple(1, 'abc', 12.33) as x, toTypeName(x);┌─x───────────────┬─toTypeName(tuple(1, \'abc\', 12.33))─┐
│ (1,'abc',12.33) │ Tuple(UInt8, String, Float64)        │
└─────────────────┴──────────────────────────────────────┘select (1, 2, 'hello') as x, toTypeName(x);
┌─x─────────────┬─toTypeName(tuple(1, 2, \'hello\'))─┐
│ (1,2,'hello') │ Tuple(UInt8, UInt8, String)        │
└───────────────┴────────────────────────────────────┘

创建tuple表及查询示例:

-- 注意:建表的时候使用元组的需要制定元组的数据类型
create table test_tuple(name String,info Tuple(String, String, UInt8)
) engine=Memory;insert into test_tuple values('zss', ('M', 'coder', 23)),('lss', tuple('F', 'coder', 23));select * from test_tuple;┌─name─┬─info─────────────┐
│ zss  │ ('M','coder',23) │
│ lss  │ ('F','coder',23) │
└──────┴──────────────────┘-- 通过下标查询tupe数据
select name, info.1, info.2, info.3 from test_tuple;┌─name─┬─tupleElement(info, 1)─┬─tupleElement(info, 2)─┬─tupleElement(info, 3)─┐
│ zss  │ M                     │ coder                 │                    23 │
│ lss  │ F                     │ coder                 │                    23 │
└──────┴───────────────────────┴───────────────────────┴───────────────────────┘

3.8 Nested 嵌套表结构

Nested 是一种嵌套表结构。一张数据表,可以定义任意多个嵌套类型字段,但每个字段的嵌套层级只支持一级,
即嵌套表内不能继续使用嵌套类型。对于简单场景的层级关系或关联关系,使用嵌套类型也是一种不错的选择。

create table test_nested (id Int8,name String,hobby Nested(hid Int8,h1 String,h2 String)
)engine=Memory;查看表结构:
┌─name──────┬─type──────────┬─default_type─┬─default_expression─┐
│ id        │ Int8          │              │                    │
│ name      │ String        │              │                    │
│ hobby.hid │ Array(Int8)   │              │                    │
│ hobby.h1  │ Array(String) │              │                    │
│ hobby.h2  │ Array(String) │              │                    │
└───────────┴───────────────┴──────────────┴────────────────────┘嵌套类型本质是一种多维数组的结构。嵌套表中每个字段都是一个数组,并且行与行之间数组的长度无须对齐。
需要注意的是,在同一行数据内每个数组字段的长度必须相等。-- 插入数据
insert into test_nested values (1, 'zss', [1,2,3],['吃','喝','睡'],['eat','drink','sleep']);
insert into test_nested values (2, 'lss', [1,2,3],['吃','喝','睡'],['eat','drink','sleep']);-- 查询数据    
select * from test_nested;┌─id─┬─name─┬─hobby.hid─┬─hobby.h1──────┬─hobby.h2────────────────┐
│  1 │ zss  │ [1,2,3]   │ ['吃','喝','睡'] │ ['eat','drink','sleep'] │
└────┴──────┴───────────┴───────────────┴─────────────────────────┘
┌─id─┬─name─┬─hobby.hid─┬─hobby.h1──────┬─hobby.h2────────────────┐
│  2 │ lss  │ [1,2,3]   │ ['吃','喝','睡'] │ ['eat','drink','sleep'] │
└────┴──────┴───────────┴───────────────┴─────────────────────────┘-- 复杂查询数据
select id, name, hobby.hid, hobby.h1, hobby.h1[1] from test_nested;┌─id─┬─name─┬─hobby.hid─┬─hobby.h1──────┬─arrayElement(hobby.h1, 1)─┐
│  1 │ zss  │ [1,2,3]   │ ['吃','喝','睡'] │ 吃                         │
└────┴──────┴───────────┴───────────────┴───────────────────────────┘
┌─id─┬─name─┬─hobby.hid─┬─hobby.h1──────┬─arrayElement(hobby.h1, 1)─┐
│  2 │ lss  │ [1,2,3]   │ ['吃','喝','睡'] │ 吃                         │
└────┴──────┴───────────┴───────────────┴───────────────────────────┘

3.9 复杂数据类型

3.9.1 domain

-- Domain pojo beans:https://clickhouse.tech/docs/zh/sql-reference/data-types/domains/ipv4/
域名类型分为IPv4和IPv6两类,本质上它们是对整型和字符串的进一步封装。IPv4类型是基于UInt32封装的

(1)出于便携性的考量,例如IPv4类型支持格式检查,格式错误的IP数据是无法被写入的,例如:INSERT INTO IPv4_test values('www.nauu.com', '192.0.0.1')

(2)出于性能的考量,同样以IPv4为例,IPv4使用UInt32存储,相比String 更加紧凑,占用的空间更小,查询性能更快。IPv6类型是基于FixedString(16) 封装的,它的使用方法与IPv4别无二致,在使用Domain类型的时候还有一点需要注意,虽然它从表象上看起来与String 一样,但Domain 类型并不是字符串,所以它不支持隐式的自动类型转换。如果需要返回IP的字符串形式,则需要显式调用IPv4NumToString 或 IPv6NumToString 函数进行转换。

create table test_domain1(id Int8,ip IPv4
)engine=Memory;insert into test_domain1 values(1, '192.168.133.1');
insert into test_domain1 values(1, '192.168.133');create table test_domain2(id Int8,ip String
)engine=Memory;insert into test_domain2 values(1, '192.168.133.1');
insert into test_domain2 values(1, '192.168.133');

四、数据库

数据库起到了命名空间的作用,可以有效规避命名冲突的问题,也为后续的数据隔离提供了支撑。任何一张数据表,都必须归属在某个数据库之下。

在CK中数据库也有自己的引擎,数据库目前支持的数据库引擎有5种:

1)Ordinary:默认引擎,在绝大多数情况下我们都会使用默认引擎,使用时无须刻意声明。在此数据库下可以使用任意类型的表引擎

2) Dictionary:字典引擎,此类数据库会自动为所有数据字典创建它们的数据表

3) Memory:内存引擎,用于存放临时数据。此类数据库下的数据表只会停留在内存中,不会涉及任何磁盘操作,当服务重启后数据会被清除

4) Lazy:日志引擎,此类数据库下只能使用Log系列的表引擎

5) MySQL:MySQL引擎,此类数据库下会自动拉取远端MySQL中的数据,并为它们创建MySQL表引擎的数据表

6)  MaterializeMySQL:MySQL数据同步;将MySQL数据全量或增量方式同步到clickhouse中,解决mysql服务并发访问压力过大的问题

4.1 MySQL 数据库引擎

MySQL数据库引擎

先在mysql中先创建好数据库db_mysql_test

  • 确认远程访问权限
  • 确认域名是否配置
create database school_score engine=MySQL('node-01:3306','school_score','root','aa_bb_CC1234');

这样就可以在clickhouse下查询mysql中的数据了

use school_score;
show tables;

在clickhouse 不能创建mysql引擎表。但可以在clickhouse插入数据到mysql;因为 clickhouse不支持delete删除数据、update更新操作;原因是clickhouse定位于olap分析,不支持事务

4.2 Log 家族【Log系列引擎】

Log家族,比较简单,数据少,测试使用,本地表,本地存储表数据。默认数据存储在:/var/lib/clickhouse/data/...

Log家族具有最小功能的轻量级引擎。当您需要快速写入许多小表(最多约100万行)并在以后整体读取它们时,该类型的引擎是最有效的

4.2.1 TinyLog引擎(数据不分块)

TinyLog引擎数据不分块,而Log会进行分块。所以效率上来说:TinyLog不如Log快,因为它是单线程的。

最简单的表引擎,用于将数据存储在磁盘上。每列都存储在单独的压缩文件中,写入时,数据将附加到文件末尾。

该引擎没有并发控制。

  1. 只支持并发读
  2. 如果同时从表中读取和写入数据,则读取操作将抛出异常;
  3. 如果同时写入多个查询中的表,则数据将被破坏。
-- 建表
create table tb_tinylog(id Int8, name String, age Int8, birthDay Date) engine=TinyLog;-- 插入数据
insert into tb_tinylog values(1,'马云',56, '1990-01-01'),(2,'马化腾',55, '1990-01-01'),(3,'马克思',123, '1990-01-01');-- 查询数据
select * from tb_tinylog;

ll /var/lib/clickhouse/data/default/test_db

-rw-r--r-- 1 root root  29 Jan 10 15:17 age.bin
-rw-r--r-- 1 root root  32 Jan 10 15:17 birthDay.bin
-rw-r--r-- 1 root root  29 Jan 10 15:17 id.bin
-rw-r--r-- 1 root root  54 Jan 10 15:17 name.bin
-rw-r--r-- 1 root root 121 Jan 10 15:17 sizes.json

数据存储在机器的磁盘上,每列一个文件,插入数据向列文件的后面追加

再插入一条数据后,存储列数据的文件的大小增加了

age.bin 和 id.bin, name.bin 是压缩过的对应的列的数据,sizes.json 中记录了每个 *.bin 文件的大小:

cat sizes.json

[root@node-01 tb_tinylog]# cat sizes.json 
{"yandex":{"age%2Ebin":{"size":"29"},"birthDay%2Ebin":{"size":"32"},"id%2Ebin":{"size":"29"},"name%2Ebin":{"size":"54"}}}[root@node-01 tb_tinylog]#

补充说明,如果表损坏,需要将表删除、表对应的元数据删除,然后重启clickhouse-server服务

[root@node-01 test_db]# rm -rf /var/lib/clickhouse/data/test_db/tb_tinylog
[root@node-01 test_db]# rm -rf /var/lib/clickhouse/metadata/test_db/tb_tinylog.sql

这种表引擎的典型用法是 write-once:

  1. 首先只写入一次数据,然后根据需要多次读取。此引擎适用于相对较小的表(建议最多1,000,000行)。
  2. 如果有许多小表,则使用此表引擎是适合的,因为它比需要打开的文件更少。当拥有大量小表时,可能会导致性能低下。不支持索引。

4.2.2 StripLog (数据分块列在一起)

在你需要写入许多小数据量(小于一百万行)的表的场景下使用这个引擎。

-- 建表
create table stripe_log_table (timestamp DateTime,message_type String,message String
) engine=StripeLog;

5、数据表

ClickHouse 数据表的定义语法,是在标准SQL的基础上建立的,所以熟悉数据库的读者们在看到接下来的语法时,应该会感到熟悉。ClickHouse 目前提供了三种最基本的建表方法!但是注意的是在CK中建表一定要指定表的引擎,那么表的引擎的详细文档在后面。

5.1 创建表

create table [if not exists] [db_name.]table_name (
name1 [type][DEFAULT|MATERLIALIZED|ALIAS expr],
name2 [type][DEFAULT|MATERLIALIZED|ALIAS expr],
省略...
) ENGINE=engine

第一种建表方式:

create table test_db.test1(id Int16 DEFAULT 0 comment '用户的标识',name String comment '用户姓名',age UInt8 comment '用户年龄'
) ENGINE=Log;

上述语句将会在default 默认的数据库下创建一张内存表。注意末尾的ENGINE 参数,它被用于指定数据表的引擎。表引擎决定了数据表的特性,也决定了数据将会被如何存储及加载。例如示例中使用的Memory表引擎,是ClickHouse最简单的表引擎,数据只会被保存在内存中,在服务重启时数据会丢失。

第二种方式建表:

这种方式其实就是复制已经存在的一张的表结构,可用于数据的备份,可用于多个数据库之间复制表结构

CREATE TABLE [IF NOT EXISTS] [db_name.]table_name AS [db_name2.]table_name2[ENGINE=engine];

示例:

create database newdb;
use newdb;-- 将复制test_db 数据库中的test1 表的表结构
create table tb_test1 as test_db.test1;
desc tb_test1;

第三种方式建表:

通过SELECT 查询的方式创建表,同时也会导入查询的结果数据

-- 语法
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name ENGINE=engine AS SELECT ...

示例

create table tb_log engine=Memory as select * from test_db.tb_tinylog;

5.2 删除表

DROP TABLE [IF EXISTS] [db_name.]table_name;

5.3 临时表

ClickHouse 也有临时表的概念,创建临时表的方法是在普通表的基础之上添加TEMPORARY 关键字,相比普通表而言,临时表也如下两点特殊之处:

  • 它的生命周期是会话绑定的,所以它只支持Memeory 表引擎,如果会话结束,数据表就会被销毁;
  • 临时表不属于任何数据库所以在它的建表语句中,既没有数据库参数也没有表引擎参数

临时表的有优先级大于系统中的表,一般用于集群之间的数据传播的载体

临时表的创建语法如下:

CREATE TEMPORARY TABLE [IF NOT EXISTS] table_name (name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr],name2 [type] [DEFAULT|MATERIALIZED|ALIAS expr],...
)-- 直接创建临时表,临时表不属于任何一个数据库,也不会持久保存,不用指定引擎
create temporary table tb_tmp(id Int8, name String); -- 临时表不需要指定表的引擎-- 创建临时表并加载数据
create temporary table log as select * from test_log;-- 将临时表的数据导入到当前数据库表中,实现不同数据库的数据迁移
create table tb_log engine=Log as select * from log;

我们可以理解成临时表会将当前数据库中已经存在的同名表覆盖隐藏,当出现操作的时候,如果有临时表,那么会操作临时表!

临时表:

  1. 不属于任何数据库
  2. 会话断开以后表删除,不会持久化
  3. 如果本地表和临时表冲突,临时表优先
  4. 数据库之间的数据迁移
create table tb_name engine=Log as select * from db.tb;create temporary table log as select * from test_db.test_log;
create table tb_log engine=Log as select * from log;

5.4 视图

5.4.1 普通视图

ClickHouse拥有普通和物化两种视图,其中物化视图拥有独立的存储,而普通视图只是一层简单的查询代理

CREATE VIEW [IF NOT EXISTS] [db_name.]view_name AS SELECT ...

普通视图不会存储任何数据,它只是一层单酏的SELECT 查询映射,起着简化查询、明晰语义的作用,对查询性能不会有任何增强。假设有一张普通视图 view_tb_v1,它是基于数据表 tb_v1创建的,那么下面的两格SELECT 查询是完全等价的。

SELECT * FROM tb_v1
-- tb_v1 的视图
SELECT * FROM view_tb_v1;

示例:

create table tb_teacher (tid Int8,name String,age UInt8,gender String,sal Float64
)engine=Log;insert into tb_teacher values(1, 'wbb', 27, 'm', 20000),(2, 'lbb', 25, 'f', 30000),(3, 'mbb', 26, 'm', 40000),(4, 'sbb', 37, 'f', 50000),(5, 'lbb', 17, 'm', 60000);create view teacher_view as select name, sal from tb_teacher;
-- 普通视图不存储数据,只是一个指向
select * from teacher_view;

5.4.2 物化视图

物化视图支持表引擎,相当于特殊的表,数据保存形式由它的表引擎决定,创建物化视图的完整语法如下所示:

create materialized view mv_log engine=Log populate as select * from log;
在磁盘上有表目录,目录中的文件和映射表的结构一样-- 物化视图 特殊的表 结构 引擎 持久化
create materialized view m_teacher_view as engine=Log populate as select * from tb_teacher;select * from m_teacher_view;-- 向普通表tb_teacher插入数据
insert into tb_teacher values(6, 'xingge', 48, 'm', 1500);-- 查询物化视图中的数据,同步数据
select * from m_teacher_view;

5.5 分区表

数据分区(partition)和数据分片(shard)是完全不同的两个概念。数据分区是针对本地数据而言的,是数据的一种纵向切分。而数据分片是数据的一种横向切分。数据分区对于一款OLAP数据库而言意义非凡:借助数据分共,在后续的查询过程中能够跳过不必要的数据目录,从而提升查询的性能。合理地利用分区特性,还可以变相实现数据的更新操作,因为数据分区支持删除、替换和重置操作。假设数据表按照月份分区,那么数据就可以按月份的粒度被替换更新。分区虽好,但不是所有的表引擎都可以使用这项特性,目前只有合并树(MergeTree)家族系列的表引擎才支持数据分区。接下来通过一个简单的例子演示分区表的使用方法。首先由PARTITION BY 指定分区键,并将其格式化为年月的形式:

create table tb_partition(cid String,ctime DateTime,money Float64
)engine=MergeTree() -- MergeTree家族最简单的引擎
partition by toYYYYMM(ctime) -- 按照年月来分区
order by cid -- 指定排序字段; 当排序字段与主键字段是同一个字段时,就会将主键字段不指定
primary key cid;-- 插入数据
insert into tb_partition values
(1, '2020-12-01 11:00:21', 100),
(2, '2020-12-02 11:12:21', 300),
(3, '2020-11-01 11:00:21', 200);-- 查询tb_partition表的分区信息
select table, partition, engine, path from system .parts where table='tb_partition';-- 再次插入数据,进入到/var/lib/clickhouse/data/test_db/tb_partition/ 会发现11、12月份的数据都各有2个块
insert into tb_partition values
(4, '2020-12-01 11:00:21', 100),
(5, '2020-12-02 11:12:21', 300),
(6, '2020-11-01 11:00:21', 200);-- 合并数据
optimize table tb_partition; -- 一次合并两个分区-- 进入到/var/lib/clickhouse/data/test_db/tb_partition/ 会发现11、12月份的数据都各有1个块
-- 之前老的分区,默认8分钟会被删除

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/449992.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

01数组算法/代码随想录

一、数组 好久没写算法题&#xff0c;之前喜欢按着习惯选择刷题&#xff0c;很早以前就听说代码随想录&#xff0c;今天跟着代码随想录再过一遍算法 1.1二分查找 常见疑问 middle一定是在[left, right]这个范围内标准代码不会越界&#xff0c;因为在else if中出现越界后&…

【windows个性化】在 Windows 10/11 上使 Windows 任务栏半透明/透明

实现目的&#xff1a;在 Windows 10/11 上使 Windows 任务栏半透明/透明. TranslucentTB plugin 描述 只需几 MB 内存&#xff0c;几乎不占用 CPU&#xff0c;便可以在 Windows 10/11 上使 Windows 任务栏半透明/透明的轻量小工具 功能 高级颜色选择器(color picker)&…

X(twitter)推特广告类型有哪些?如何选择?

X&#xff08;twitter&#xff09;推特是全球最热门的几大社交媒体平台之一&#xff0c;也是很多电商卖家进行宣传推广工作的阵地之一。在营销过程中不可避免地需要借助平台广告&#xff0c;因此了解其广告类型和适配场景也十分重要。 一、广告类型及选择 1.轮播广告 可滑动的…

JavaScript的100个概念

JavaScript对初学者来说既是福音&#xff0c;也是挑战。一方面&#xff0c;掌握它后可以构建各种项目&#xff0c;比如网站、应用程序和服务器&#xff0c;还能在很多行业找到工作。但另一方面&#xff0c;它又充满怪异之处&#xff0c;并被各种复杂的库和框架包围。在这段课程…

FLUX LoRA模型揭秘:COMFYUI中的AI绘画新动力!

嗨&#xff0c;艺术爱好者们&#xff01;今天我们要揭开一个神秘的面纱——FLUX LoRA模型&#xff0c;这个模型就像是一个神奇的魔法师&#xff0c;将COMFYUI中的AI绘画提升到了一个新的高度&#xff01; 想象一下&#xff0c;你有一个AI助手&#xff0c;它能够理解你的绘画梦…

【Redis】Zset类型常用命令

文章目录 一. Zset有序集合简介.二. 添加元素相关命令.2.1 向有序集合中添加元素(zadd) 三. 查询元素相关操作.3.1 查询有序集合中的元素个数( zcard zcount)3.2 查询指定区间内的元素(zrange zrevrange zrangebyscore)3.3 查询有序集合中指定成员的排名(zrank zrevrank )3.4 查…

钴粉Co纳米微球100nm|CoNP/CoN2-C催化剂

钴粉Co纳米微球100nm|CoNP/CoN2-C催化剂 钴粉Co纳米微球100nm是一种具有独特物理和化学性质的纳米材料&#xff0c;因其高比表面积、优良的磁性和化学稳定性&#xff0c;在多个领域展现出广阔的应用前景。以下是关于钴粉Co纳米微球100nm的相关信息&#xff1a; 性质 高比表面…

ubuntu20.04安装gerrit

1、update 2、updategrale 一&#xff1a;安装前准备 配置管理gerrit的专属账号&#xff1a;(本次测试安装我用的ROOT) sudo adduser gerrit sudo usermod -a -G sudo gerrit //分配sudo 权限 sudo su gerrit java、git环境&#xff1a; sudo apt-get update sudo apt-g…

群晖前面加了雷池WAF,安装失败,然后无法识别出用户真实访问IP

有nas的相信对公网都不模式&#xff0c;在现在基础上传带宽能有100兆的时代&#xff0c;有公网代表着家里有一个小服务器&#xff0c;像百度网盘&#xff0c;优酷这种在线服务都能部署为私有化服务。但现在运营商几乎不可能提供公网ip&#xff0c;要么自己买个云服务器做内网穿…

多jdk版本环境下,jenkins系统设置需指定JAVA_HOME环境变量

一、背景 由于不同项目对jdk版本的要求不同&#xff0c;有些是要求jdk11&#xff0c;有些只需要jdk8即可。 而linux机器上安装jdk的方式又多种多样&#xff0c;最后导致jenkins打包到底使用的是哪个jdk&#xff0c;比较混乱。 1、java在哪 > whereis java java: /usr/bin/…

测试人生 | 双非院校,2年工作经验年薪近20万

本人本科毕业于双非院校&#xff0c;大学毕业之后就开始从事软件测试工作&#xff0c;有两年多的工作经验&#xff0c;工作当中学习的测试技能较少&#xff0c;比较多重复的工作内容&#xff0c;主要对软件进行功能测试、简单的接口测试及专项测试&#xff0c;自学的测试知识零…

【STL】模拟实现list

目录 list需要实现的接口 结点类的创建 迭代器类的实现 构造函数 运算符的重载 --运算符的重载 !运算符重载和运算符重载 operator* operator-> list的模拟实现 构造函数 拷贝构造函数 赋值运算符重载函数 析构函数 迭代器相关函数 begin和end front和back …

【超详细】TCP协议

TCP(Transmission Control Protocol 传输控制协议) 传输层协议有连接可靠传输面向字节流 为什么TCP是传输控制协议呢&#xff1f; 我们以前所看到的write接口&#xff0c;都是把用户级缓冲区的数据拷贝到发送缓冲区中&#xff0c;然后数据就由TCP自主决定了&#xff0c;所以…

crashrpt3 开源项目的Vs 2022 C++20及其以上的编译

1. 首先从github 下载源代码 crashrpt3 2. 用CMake Gui 编译成vs studio 工程文件 2.1 点击 config 按钮 2.2 依次点击 Generate 按钮、Open Project 按钮.之后vs 2022 会打开编译好的sln工程文件 3.全选解决方案里面的所有项目,设置C语言标准,我这里设置是最新C,即启用的是…

【文档智能】文本文字识别、公式识别、表格文字识别核心算法及思路及实践-DBNet、CRNN、TrOCR

前言 OCR技术作为文档智能解析链路中的核心组件之一&#xff0c;贯穿整个技术链路&#xff0c;包括&#xff1a;文字识别、表格文字识别、公式识别&#xff0c;参看下面这张架构图&#xff1a; 前期介绍了很多关于文档智能解析相关核心技术及思路&#xff0c;本着连载的目的&a…

IT监控平台可视化:多维度展示助力运维效率提升

在信息化时代&#xff0c;IT设备的稳定性与业务的连续性紧密相连&#xff0c;任何细微的故障都可能给企业带来巨大的损失。因此&#xff0c;IT运维团队面临着前所未有的挑战&#xff0c;他们需要迅速、准确地识别和解决问题&#xff0c;以确保业务的平稳运行。而IT监控平台的可…

应届生毕业找不到工作转行IT需要做好哪些准备呢?

前言 相信这是很多即将毕业的应届生们都非常关心的问题。在这里&#xff0c;我们将站在一个应届生毕业且对IT行业感兴趣的角度&#xff0c;来探讨一下这个问题。 首先&#xff0c;我们先来了解一下什么是应届生。应届生是指在学校毕业之后&#xff0c;能够在当年或者下一年度…

AIGC验证码如何对抗,AIGC VS AIGC

AI类型的验证码&#xff0c;当然使用AI对对抗&#xff0c;使用大量的样本叠加训练&#xff0c;我的生成如下: 如果可以生词大量词汇&#xff0c;那么准确率必然上升&#xff0c;有办法的可以讨论

大模型系列:RAG技术深度解析

文末有福利&#xff01; RAG 是2023年最流行的基于 LLM 的应用系统架构。有许多产品几乎完全建立在 RAG 之上&#xff0c;覆盖了结合网络搜索引擎和 LLM 的问答服务&#xff0c;到成千上万个数据聊天的应用程序。很多人将RAG和Agent 作为大模型应用的两种主流架构&#xff0c;…

CTFHUB技能树之HTTP协议——响应包源代码

开启靶场&#xff0c;打开链接&#xff1a; 是个贪吃蛇小游戏&#xff0c;看不出来有什么特别的地方 用burp抓包看看情况&#xff1a; 嗯&#xff1f;点击“开始”没有抓取到报文&#xff0c;先看看网页源代码是什么情况 居然直接给出flag了&#xff0c;不知道这题的意义何在 …