首页 > 其他分享 >ClickHouse 表引擎简介(一)

ClickHouse 表引擎简介(一)

时间:2022-11-07 16:47:48浏览次数:46  
标签:sku 00 简介 08 引擎 ClickHouse 2022 102 clickhouse

1、表引擎介绍

ClickHouse表引擎是ClickHouse的一大特色。可以说, 表引擎决定了如何存储表的数据。包括:

  • 数据的存储方式和位置,写到哪里以及从哪里读取数据。
  • 支持哪些查询以及如何支持。
  • 并发数据访问。
  • 索引的使用(如果存在)。
  • 是否可以执行多线程请求。
  • 数据复制参数。

表引擎的使用方式就是必须显式在创建表时定义该表使用的引擎,以及引擎使用的相关参数。说明:表引擎的大小写敏感,在写建表语句的时候需要注意一下。

2、TinyLog

TinyLog 是最简单的表引擎,用于将数据存储在磁盘上。每列都存储在单独的压缩文件中,写入时,数据将附加到文件末尾。该引擎没有并发控制 - 如果同时从表中读取和写入数据,则读取操作将抛出异常; - 如果同时写入多个查询中的表,则数据将被破坏。 这种表引擎的典型用法是 write-once:首先只写入一次数据,然后根据需要多次读取。此引擎适用于相对较小的表(建议最多1,000,000行)。如果有许多小表,则使用此表引擎是适合的,因为它比需要打开的文件更少。当拥有大量小表时,可能会导致性能低下。  不支持索引。 下面使用 TinyLog  建表
create table t_tinylog ( id String, name String) engine=TinyLog;
此时我们到保存数据的目录/var/lib/clickhouse/data/default/t_tinylog 中可以看到如下目录结构:
[root@hadoop201 hui]# ll /var/lib/clickhouse/data/default/t_tinylog/
total 12
-rw-r----- 1 clickhouse clickhouse 31 May 19 15:04 id.bin
-rw-r----- 1 clickhouse clickhouse 33 May 19 15:04 name.bin
-rw-r----- 1 clickhouse clickhouse 64 May 19 15:04 sizes.json
其中 id.bin name.bin 是压缩后的数据
[root@hadoop201 hui]# less /var/lib/clickhouse/data/default/t_tinylog/sizes.json 
{"yandex":{"id%2Ebin":{"size":"31"},"name%2Ebin":{"size":"33"}}}

3、Memory

内存引擎,数据以未压缩的原始形式直接保存在内存当中,服务器重启数据就会消失。读写操作不会相互阻塞,不支持索引。简单查询下有非常非常高的性能表现(超过10G/s)。一般用到它的地方不多,除了用来测试,就是在需要非常高的性能,同时数据量又不太大(上限大概 1 亿行)的场景。

4、MergeTree

MergeTree 是ClickHouse中最强大的表引擎当属MergeTree(合并树)引擎及该系列(*MergeTree)中的其他引擎,支持索引和分区,地位可以相当于innodb之于Mysql。 而且基于MergeTree,还衍生除了很多小弟,也是非常有特色的引擎。

建表

create table t_order_mt(
    id UInt32,
    sku_id String,
    total_amount Decimal(16,2),
    create_time  Datetime
 ) engine =MergeTree  #指定引擎
   partition by toYYYYMMDD(create_time) #分区字段
   primary key (id) #主键:这里的主键可以重复
   order by (id,sku_id); #排序字段
插入数据
insert into  t_order_mt values
(101,'sku_001',1000.00,'2022-08-01 12:00:00') ,
(102,'sku_002',2000.00,'2022-08-01 11:00:00'),
(102,'sku_004',2500.00,'2022-08-01 12:00:00'),
(102,'sku_002',2000.00,'2022-08-01 13:00:00'),
(102,'sku_002',12000.00,'2022-08-01 13:00:00'),
(102,'sku_002',600.00,'2022-08-02 12:00:00');
查询一下:这里分两个区
hadoop201 :) sselect * from t_order_mt;select * from t_order_mt;


Query id: 49765984-11f1-43e0-b453-b291fe04655c

┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 101 │ sku_001 │      1000.00 │ 2022-08-01 12:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 11:00:00 │
│ 102 │ sku_004 │      2500.00 │ 2022-08-01 12:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_002 │     12000.00 │ 2022-08-01 13:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘
┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 102 │ sku_002 │       600.00 │ 2022-08-02 12:00:00 │
需要注意:通过ClickHouse 自带的 client 查询有分区效果,但是通过第三方工具连接ClickHouse 查询是没有分区效果的;下面是Datagrip的查询效果
101    sku_001    1000.00    2022-08-01 04:00:00
102    sku_002    2000.00    2022-08-01 03:00:00
102    sku_004    2500.00    2022-08-01 04:00:00
102    sku_002    2000.00    2022-08-01 05:00:00
102    sku_002    12000.00    2022-08-01 05:00:00
102    sku_002    600.00    2022-08-02 04:00:00
MergeTree其实还有很多参数(绝大多数用默认值即可),但是三个参数是更加重要的,也涉及了关于MergeTree的很多概念。

4.1、partition by 分区 (可选项)

作用:分区的目的主要是降低扫描的范围,优化查询速度; 如果不填:只有一个分区;all 分区目录:MergeTree 是以列文件+索引文件+表定义文件组成的,但是如果设定了分区那么这些文件就会保存到不同的分区目录中。 并行:分区后,面对涉及跨分区的查询统计,ClickHouse会以分区为单位并行处理。
[root@hadoop201 clickhouse]# pwd
/var/lib/clickhouse
[root@hadoop201 clickhouse]# ll
total 4
drwxr-x---  2 clickhouse clickhouse 116 Aug  2 09:00 access
drwxr-x---  3 clickhouse clickhouse  33 Aug  6 21:07 backup
drwxr-x---  2 clickhouse clickhouse   6 Aug  2 09:00 cores
drwxr-x---  6 clickhouse clickhouse  70 Aug  6 15:31 data #数据文件
drwxr-x---  2 clickhouse clickhouse   6 Aug  2 09:00 dictionaries_lib
drwxr-x---  2 clickhouse clickhouse   6 Aug  2 09:00 flags
drwxr-x---  2 clickhouse clickhouse   6 Aug  2 09:00 format_schemas
drwxr-x---  3 clickhouse clickhouse 150 Aug  6 15:31 metadata #元数据
drwxr-x---  2 clickhouse clickhouse   6 Nov  5 23:24 metadata_dropped
drwxr-x---  2 clickhouse clickhouse  41 Aug  2 09:00 preprocessed_configs
drwxr-x---  2 clickhouse clickhouse  27 Aug  6 21:07 shadow
-rw-r-----  1 clickhouse clickhouse  58 Nov  5 17:34 status
drwxr-x--- 28 clickhouse clickhouse 292 Nov  5 23:16 store
drwxr-x---  2 clickhouse clickhouse   6 Aug  2 09:00 tmp
drwxr-x---  2 clickhouse clickhouse   6 Aug  2 09:00 user_files
[root@hadoop201 metadata]# pwd
/var/lib/clickhouse/metadata
drwxr-xr-x 2 clickhouse clickhouse 46 Aug  4 15:16 datasets
-rw-r----- 1 clickhouse clickhouse 43 Aug  4 15:17 datasets.sql
lrwxrwxrwx 1 clickhouse clickhouse 67 Aug  2 09:00 default -> /var/lib/clickhouse/store/1db/1dbec0d7-a9c7-43b8-9dbe-c0d7a9c753b8/
-rw-r----- 1 clickhouse clickhouse 78 Aug  2 09:00 default.sql
lrwxrwxrwx 1 clickhouse clickhouse 67 Aug  2 09:00 system -> /var/lib/clickhouse/store/27d/27d15ac3-28bb-4586-a7d1-5ac328bb7586/
-rw-r----- 1 clickhouse clickhouse 78 Aug  2 09:00 system.sql
存放每个数据库下表的建表语句
[root@hadoop201 default]# pwd
/var/lib/clickhouse/metadata/default 
[root@hadoop201 default]# ll
total 4
-rw-r----- 1 clickhouse clickhouse 290 Aug  3 15:23 t_order_mt.sql 
#建表语句
[root@hadoop201 default]# less t_order_mt.sql 
ATTACH TABLE _ UUID 'f86dc6d3-aec1-493e-b86d-c6d3aec1293e'
(
    `id` UInt32,
    `sku_id` String,
    `total_amount` Decimal(16, 2),
    `create_time` DateTime
)
ENGINE = MergeTree
PARTITION BY toYYYYMMDD(create_time)
PRIMARY KEY id
ORDER BY (id, sku_id)
SETTINGS index_granularity = 8192
数据其实存储在 /var/lib/clickhouse/store,但是下面的目录不方便阅读,软连接到来/var/lib/clickhouse/data
[root@hadoop201 t_order_mt]# pwd
/var/lib/clickhouse/data/default/t_order_mt
[root@hadoop201 t_order_mt]# ll
total 4
drwxr-x--- 2 clickhouse clickhouse 203 Aug  3 15:25 20220801_1_1_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  3 15:25 20220802_2_2_0
drwxr-x--- 2 clickhouse clickhouse   6 Aug  3 15:23 detached
-rw-r----- 1 clickhouse clickhouse   1 Aug  3 15:23 format_version.txt
文件说明:
bin 文件是数据文件
mrk 文件是标记文件:标记文件在 idx索引文件和bin 数据文件起到桥梁作用
primark.idx 文件主键索引文件,用于加快查询效率
minmax_create_time.idx 分区键最大最小指
checksums.txt 校验文件,用于校验各文件的正确性,存放各文件的size和hash值
文件格式说明
20220801_  1_1_0  第一个1 表示最小分区块编号,第二个1 表示最大分区块编号 0 表示合并等级
文件说明
[root@hadoop201 t_order_mt]# cd 20220801_1_1_0
[root@hadoop201 20220801_1_1_0]# ll
total 36
-rw-r----- 1 clickhouse clickhouse 259 Nov  5 23:16 checksums.txt #校验信息
-rw-r----- 1 clickhouse clickhouse 118 Nov  5 23:16 columns.txt #列信息
-rw-r----- 1 clickhouse clickhouse   1 Nov  5 23:16 count.txt #当前分区记录数
-rw-r----- 1 clickhouse clickhouse 194 Nov  5 23:16 data.bin #数据文件
-rw-r----- 1 clickhouse clickhouse 144 Nov  5 23:16 data.mrk3 #标记
-rw-r----- 1 clickhouse clickhouse  10 Nov  5 23:16 default_compression_codec.txt
-rw-r----- 1 clickhouse clickhouse   8 Nov  5 23:16 minmax_create_time.idx #分区内最大最小值
-rw-r----- 1 clickhouse clickhouse   4 Nov  5 23:16 partition.dat #分区
-rw-r----- 1 clickhouse clickhouse   8 Nov  5 23:16 primary.idx #主键索引
数据写入和分区合并:任何一个批次的数据写入都会产生一个临时分区,不会纳入任何一个已有的分区。写入后的某个时刻(大概10-15分钟后),ClickHouse会自动执行合并操作(等不及也可以手动通过optimize执行),把临时分区的数据,合并到已有分区中
optimize table tabName final;
再次插入数据
insert into  t_order_mt values
(101,'sku_001',1000.00,'2022-08-01 12:00:00') ,
(102,'sku_002',2000.00,'2022-08-01 11:00:00'),
(102,'sku_004',2500.00,'2022-08-01 12:00:00'),
(102,'sku_002',2000.00,'2022-08-01 13:00:00'),
(102,'sku_002',12000.00,'2022-08-01 13:00:00'),
(102,'sku_002',600.00,'2022-08-02 12:00:00');
查看数据并没有纳入任何分区
hadoop201 :) select * from t_order_mt;

SELECT *
FROM t_order_mt

Query id: 1bc4f73d-68c4-4f37-a4ab-e1b51bc1673b

┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 102 │ sku_002 │       600.00 │ 2022-08-02 12:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘
┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 102 │ sku_002 │       600.00 │ 2022-08-02 12:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘
┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 101 │ sku_001 │      1000.00 │ 2022-08-01 12:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 11:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_002 │     12000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_004 │      2500.00 │ 2022-08-01 12:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘
┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 101 │ sku_001 │      1000.00 │ 2022-08-01 12:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 11:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_002 │     12000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_004 │      2500.00 │ 2022-08-01 12:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘
└─────┴─────────┴──────────────┴─────────────────────┘
文件展示
[root@hadoop201 t_order_mt]# pwd
/var/lib/clickhouse/data/default/t_order_mt
[root@hadoop201 t_order_mt]# ll
total 4
drwxr-x--- 2 clickhouse clickhouse 203 Aug  3 15:25 20220801_1_1_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  4 04:44 20220801_3_3_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  3 15:25 20220802_2_2_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  4 04:44 20220802_4_4_0
drwxr-x--- 2 clickhouse clickhouse   6 Aug  3 15:23 detached
手动optimize之后
hadoop201 :) optimize table t_order_mt final;
再次查询
hadoop201 :) optimize table t_order_mt final;

OPTIMIZE TABLE t_order_mt FINAL

Query id: 4ba36fcd-654a-478b-85dc-1b1c724698bc

Ok.

0 rows in set. Elapsed: 0.006 sec. 

hadoop201 :) select * from t_order_mt;

SELECT *
FROM t_order_mt

Query id: 622e35d8-e5b5-41ad-bd49-69945bd05ba8

┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 102 │ sku_002 │       600.00 │ 2022-08-02 12:00:00 │
│ 102 │ sku_002 │       600.00 │ 2022-08-02 12:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘
┌──id─┬─sku_id──┬─total_amount─┬─────────create_time─┐
│ 101 │ sku_001 │      1000.00 │ 2022-08-01 12:00:00 │
│ 101 │ sku_001 │      1000.00 │ 2022-08-01 12:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 11:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_002 │     12000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 11:00:00 │
│ 102 │ sku_002 │      2000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_002 │     12000.00 │ 2022-08-01 13:00:00 │
│ 102 │ sku_004 │      2500.00 │ 2022-08-01 12:00:00 │
│ 102 │ sku_004 │      2500.00 │ 2022-08-01 12:00:00 │
└─────┴─────────┴──────────────┴─────────────────────┘

12 rows in set. Elapsed: 0.009 sec. 

查看文件

[root@hadoop201 t_order_mt]# ll
total 4
drwxr-x--- 2 clickhouse clickhouse 203 Aug  3 15:25 20220801_1_1_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  4 04:46 20220801_1_3_1
drwxr-x--- 2 clickhouse clickhouse 203 Aug  4 04:44 20220801_3_3_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  3 15:25 20220802_2_2_0
drwxr-x--- 2 clickhouse clickhouse 203 Aug  4 04:46 20220802_2_4_1
drwxr-x--- 2 clickhouse clickhouse 203 Aug  4 04:44 20220802_4_4_0
drwxr-x--- 2 clickhouse clickhouse   6 Aug  3 15:23 detached
等到合并文件后 会删除之前的文件,可以对单独分区内数据进行合并
optimize table t_order_mt partition '20220801' final;

4.2、primary key主键(可选)

ClickHouse中的主键,和其他数据库不太一样,它只提供了数据的一级索引,但是却不是唯一约束。这就意味着是可以存在相同primary key的数据的。主键的设定主要依据是查询语句中的where 条件。根据条件通过对主键进行某种形式的二分查找,能够定位到对应的index granularity,避免了全表扫描。index granularity: 直接翻译的话就是索引粒度,指在稀疏索引中两个相邻索引对应数据的间隔。ClickHouse中的MergeTree默认是8192。官方不建议修改这个值,除非该列存在大量重复值,比如在一个分区中几万行才有一个不同数据。  

4.3、order by (必选)

order by 设定了分区内的数据按照哪些字段顺序进行有序保存。order by是MergeTree中唯一一个必填项,甚至比primary key 还重要,因为当用户不设置主键的情况,很多处理会依照order by的字段进行处理(比如后面会讲的去重和汇总)。要求:主键必须是order by字段的前缀字段。比如order by 字段是 (id,sku_id)  那么主键必须是id 或者(id,sku_id) ;

标签:sku,00,简介,08,引擎,ClickHouse,2022,102,clickhouse
From: https://www.cnblogs.com/wdh01/p/16865575.html

相关文章

  • SWIG:SWIG的简介、安装、使用方法之详细攻略
    SWIG:SWIG的简介、安装、使用方法之详细攻略一个处女座的程序猿于2019-12-1610:57:12发布14957收藏58分类专栏:Tool/IDEetc版权Tool/IDEetc专栏收录该内容72篇......
  • Web前端技术简介
    Web前端就是1美工photoshop、css2界面友好(比如京东=,你购物以后的关联产品是放在左边还是右边呢?)3强大的脚本功能支持(QQ空间,上传照片,重新部署......
  • AI 模型编译器 MegCC 开源,解决推理引擎体积问题
    目前社区已经有多个移动端深度学习推理框架,如:NCNN、MNN...这些推理引擎都给社区的用户带来了在移动端上部署深度学习非常多的便利,但是他们也都有一个共性问题:随着不断地迭......
  • 汽车常识之动力系统简介
    前言在人生的道路上,从来没有全身而退,坐享其成,不劳而获一说。你不努力,就得出局。一、动力系统简介是给汽车提供驱动力的总要部件;包含发动机、电动机、发电机、动力电池......
  • 01 Sonic - 简介
    1、开源测试工具Sonic介绍​​开源云真机测试平台开源啦!-设计思路与背景(一)​​2、官网​​https://sonic-cloud.gitee.io/#/Home​​ 3、源码git地址​​https://github......
  • Emmet 简介、语法和速查
    1 Emmet简介Emmet是一个文本编辑器/IDE的插件,使用Emmet通过简短的表达式来快速生成复杂的HTML/CSS代码片段,只要掌握一些常用的语法,可以减少重复编码的工作,帮助我们快速开发......
  • 一张图展示齐博X1目录结构简介
    这里所写的就是比较重要的.需要大家了解的.没标注的.就是大家可以不需要了解的.因为用的不多的.大家无需关注的.点击查看大图......
  • Numpy与Pandas简介
    一、Numpy与Pandas是什么?Numpy(NumericalPython)是Python语言的一个第三方库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库。Numpy是一个运行......
  • AOP-简介,面向切面编程好处,AOP编程术语,AspectJ(通知类型,切入点表达式)
    AOP概述1.AOP简介AOP(AspectOrientProgramming),面向切面编程。面向切面编程是从动态角度考虑程序运行过程。AOP底层,就是采用动态代理模式实现的。采用了两种代......
  • 比特币与以太坊的基本知识简介
    比特币是由中本聪提出的一种数字货币。比特币不依靠任何货币机构,是一种去中心化的记账机制,由所有节点共同维护一个账本,用户的比特币信息通过这个账本计算所得。POW比特......