跟着chatgpt一起学|2.Clickhouse入门(2)

跟着chatgpt一起学|2.clickhouse入门(1)-CSDN博客

chatgpt规划的学习路径如下:

目录

2.数据建模和表设计

2.1 数据模型和表设计原则

2.1.1 什么是LowCardinality类型?

2.1.2 什么是数据分片?

2.2 ClickHouse支持的数据类型和索引类型

2.2.1  ClickHouse支持的数据类型

2.2.2  ClickHouse支持的索引类型

1. 主键索引(Primary Key Index)

2. 辅助索引(Secondary Indexes)

2.2.3 Clickhouse支持的索引类型举例

1.创建一个带有主键和`minmax`索引的表

2.创建带有 `set` 索引的表的示例

3.创建带有 `ngrambf_v1` 索引的表的示例

4.创建带有 `ngrambf_v1` 索引的表的示例

5.创建投影索引的示例


2.数据建模和表设计

2.1 数据模型和表设计原则

ClickHouse是一个面向列的数据库管理系统,它的数据模型和表设计原则反映了这个特性。以下是一些关键的数据模型和表设计原则

1. 列式存储
    ClickHouse的数据是按列存储的,这意味着同一列中的数据是连续存储的。这种存储方式非常适合执行聚合操作,因为它可以快速读取单一列的大量数据,并在内存中进行有效的向量化计算。

2. 数据分区
    在ClickHouse中,表通常会被分区来提高查询性能和数据管理效率。分区通常是基于时间或其他逻辑进行的,例如,可以按月或按年来分区事件数据。这样做可以减少查询不需要的数据,因为系统可以针对特定的分区执行查询。

3. 主键和索引
    ClickHouse的表可以定义主键,用于对数据进行排序和创建索引。主键不需要是唯一的,但它决定了数据的物理排序方式。良好设计的主键可以显著提高某些类型查询的性能。

4. 数据分片
    为了提高大规模数据集的处理能力和容错性,ClickHouse支持在多个节点间分布数据。数据分片允许表在不同的服务器上存储数据的不同部分,从而可以并行处理查询。

5. 数据压缩
    由于列式存储,相同列的数据类型是一样的,这使得数据可以高效压缩,节省存储空间。ClickHouse使用多种压缩算法来减少磁盘空间的使用。

6. 数据类型选择
    在设计表时,应该选择最合适的数据类型。例如,如果一个字段只存储几种状态,可以使用枚举类型而不是字符串类型。

7. 冗余与去范式化
    为了提高查询性能,ClickHouse中的表设计通常倾向于去范式化。这意味着可以在表中存储冗余数据来避免复杂的连接操作。

8. 物化视图和汇总表
    ClickHouse支持物化视图和汇总表,这些可以用来存储预计算的聚合数据,从而加快聚合查询的速度。

9. 使用LowCardinality类型
    针对具有大量重复值的字符串列,可以使用`LowCardinality`数据类型来优化存储和查询性能。

综上所述,ClickHouse的表设计原则主要集中在利用其列式存储的优势,通过合理的数据分区、分片、主键选择和压缩策略来优化性能和存储效率。

2.1.1 什么是LowCardinality类型?

在ClickHouse数据库中,`LowCardinality` 数据类型是一种用于优化存储和查询性能的特殊数据类型。它旨在用于那些具有相对较低基数(cardinality,即唯一值的数量)的列。换句话说,当一个列中的值重复率很高时,`LowCardinality` 数据类型特别有用。 `LowCardinality` 数据类型实现了对常见值的字典编码(dictionary encoding),其中每个唯一值都被映射到一个数字标识符。在数据存储时,只存储这些标识符而不是重复的值,这样可以显著减少存储空间并提高查询效率。

例如,如果你有一个字符串类型的列,其中包含大量重复的国家名称,使用 `LowCardinality(String)` 可以减少存储占用,并加快过滤和聚合操作,因为操作可以在数字标识符上执行,而不需要处理完整的字符串值。 要注意的是,`LowCardinality` 数据类型最适合那些基数不会随着时间变化而大幅增长的场景。如果基数随着时间的推移而显著增加,字典的大小和管理开销也会增长,这可能会降低性能。 使用 `LowCardinality` 数据类型时,可以在创建表或添加列时指定,例如:

CREATE TABLE example (
    id UInt32,
    country LowCardinality(String),
    ...
) ENGINE = ...

上述创建表的SQL语句定义了一个带有 `LowCardinality(String)` 类型的 `country` 字段。

2.1.2 什么是数据分片?

在 ClickHouse 中,数据分片(Sharding)是指将数据按照某种规则分布到不同的物理服务器上的过程,这样可以将数据和查询负载分散到多个节点,从而提高系统的水平扩展性和查询处理能力。

ClickHouse 是一个用于联机分析处理(OLAP)的列式数据库管理系统,它可以通过数据分片和复制来实现高性能和高可用性。在 ClickHouse 的分布式架构中,每个节点可以存储整个数据库的一部分数据,而整个集群的节点共同形成了一个单一的逻辑数据库。

数据分片的关键在于选择一个合适的分片键(Sharding Key)。分片键决定了数据如何在不同的节点之间分配。例如,可以根据一个列的值(如用户ID、时间戳或任何其他字段)来分片数据,使得具有相同或相似键值的数据位于同一个分片上。ClickHouse 使用分片键对数据进行哈希,然后根据哈希值分配到不同的分片。

ClickHouse 支持自定义分片策略,允许使用不同的函数来决定数据的分布方式。例如,可以使用以下方式在创建分布式表时指定分片策略:

CREATE TABLE distributed_table AS local_table
ENGINE = Distributed(cluster, database, table, sharding_key);

在这个例子中,`Distributed` 引擎创建了一个分布式表,其中 `cluster` 指定了要使用的集群配置(通常在配置文件中定义),`database` 和 `table` 指定了本地表的名称,这表明分布式表会将数据分发到指定集群的每个节点上的这个本地表中。`sharding_key` 是用于数据分片的键。

数据分片允许ClickHouse执行分布式查询,其中查询会被发送到多个分片,并在各个分片上并行执行。然后,每个分片的结果会被收集并合并,以形成最终的查询结果。这种方式可以大幅提升处理大数据集的能力,是 ClickHouse 应对大规模数据挑战的关键特性之一。

2.2 ClickHouse支持的数据类型和索引类型

2.2.1  ClickHouse支持的数据类型

1. 数值类型:
    `Int8`, `Int16`, `Int32`, `Int64`, `Int128`, `Int256`  有符号整数
    `UInt8`, `UInt16`, `UInt32`, `UInt64`, `UInt128`, `UInt256`  无符号整数
    `Float32`, `Float64`  浮点数
    `Decimal(P, S)`  定点数,P 是精度,S 是小数点后的位数

2. 字符串类型:
    `String`  字符串
    `FixedString(N)`  长度固定的字符串,N 为长度

3. 日期和时间类型:
    `Date`  日期
    `DateTime`  时间戳
    `DateTime64`  高精度时间戳

4. 数组类型:
    `Array(T)`  T 表示数组元素的类型

5. 枚举类型:
    `Enum8`, `Enum16`  枚举类型

6. 复合类型:
    `Tuple(T1, T2, ...)`
    `Nested`  类似于有结构的数组

7. 地理信息系统类型:
    `Point`, `Ring`, `Polygon`, `MultiPolygon`  地理空间数据类型

8. 特殊类型:
    `IPv4`, `IPv6`  IP 地址
    `UUID`  通用唯一标识符
    `LowCardinality(T)`  低基数优化的类型,T 是基础数据类型

9. Nullable 类型:
    `Nullable(T)`  可以包含 NULL 的数据类型,T 是基础数据类型

10.低基数类型

    `LowCardinality(T)` - 用于优化具有低基数值的列的存储,T 是基础数据类型,例如   `LowCardinality(String)`

2.2.2  ClickHouse支持的索引类型

1. 主键索引(Primary Key Index)


   这是用于快速数据分区(数据存储和检索)的索引。在创建表时指定,并且不能更改。ClickHouse 使用主键索引来快速缩小数据扫描的范围。例如,如果我们有一个按日期分区的表,主键可以是 `(EventDate, EventTime)`。

2. 辅助索引(Secondary Indexes)


   这些是非物化的(投影索引不完全是),用于提高查询性能的索引。ClickHouse 有几种类型的辅助索引:
   

  •    跳跃索引(Skipping Indexes):

   当查询执行时,跳跃索引会帮助系统跳过不包含所需数据的数据块。
   - `minmax` 索引,可以在查询时跳过不满足条件的数据块,以加快查询速度。
   - `set`索引,基于集合的索引
   - `tokenbf_v1` 索引可以创建布隆过滤器索引,用于快速检索包含特定词汇的数据。
   - `ngrambf_v1` 同上
     

  •    投影索引(Projection Indexes):

     投影索引是表中列的子集,可以存储为独立的结构,以加快特定查询的执行。投影可以包括列的物化视图,也可以包括通过表达式计算出的数据。

2.2.3 Clickhouse支持的索引类型举例

1.创建一个带有主键和`minmax`索引的表
CREATE TABLE example_table
(
    EventDate Date,
    EventTime DateTime,
    EventName String,
    EventValue Float64,
    INDEX minmax_event_time_idx EventTime TYPE minmax GRANULARITY 3
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(EventDate)
ORDER BY (EventDate, EventTime);

在这个例子中,`EventDate` 和 `EventTime` 是主键索引的一部分,而 `minmax_event_time_idx` 是一个跳跃索引。主键索引大家都比较熟悉了,minmax索引的工作机制如下:

  • 粒度

        索引粒度定义了多少个数据块会被放在一起进行索引。在这个例子中,粒度为 3 意味着每 3 个数据块会有一个单独的索引项。

  • 索引项

        每个索引项记录了对应的数据块组(在这里是每 3 个数据块)中 `EventTime` 字段的最小值和最大值。

  • 查询优化

        当执行一个查询时,如果查询条件涉及到 `EventTime` 字段,ClickHouse 会检查每个索引项,以确定是否有必要读取对应的数据块。例如,如果查询是寻找在某个特定时间范围内的事件,ClickHouse 会使用 `minmax` 索引来快速跳过那些时间范围完全不重叠的数据块。

例如我们有一个查询:

SELECT *
FROM example_table
WHERE EventTime >= '2023-01-01 12:00:00' AND EventTime <= '2023-01-01 13:00:00';

在这个查询中,我们寻找 `EventTime` 在 '2023-01-01 12:00:00' 到 '2023-01-01 13:00:00' 之间的事件。ClickHouse 会检查 `minmax_event_time_idx` 索引来确定哪些数据块组可能包含这个时间范围内的数据。如果某个数据块组的最大值小于 '2023-01-01 12:00:00' 或最小值大于 '2023-01-01 13:00:00',那么这个数据块组就不会包含满足条件的 `EventTime`,因此可以跳过,不用读取和处理。
`minmax` 索引可以显著加快针对时间范围的查询,尤其是当数据集非常大时。通过减少需要读取的数据块数量,`minmax` 索引有助于降低磁盘 I/O,从而提高查询性能。然而,每个索引都有一定的存储开销,并且在插入数据时需要计算,所以使用时要根据实际情况进行权衡。

2.创建带有 `set` 索引的表的示例
CREATE TABLE example_table
(
    event_type String,
    event_date Date,
    event_data String,
    INDEX event_type_idx event_type TYPE set(0) GRANULARITY 4
)
ENGINE = MergeTree()
PARTITION BY toYYYYMM(event_date)
ORDER BY (event_date, event_type);

整体和前面的minmax类似。

3.创建带有 `ngrambf_v1` 索引的表的示例

该索引基于 N-gram 和布隆过滤器(Bloom filter)技术,可以有效减少在执行包含 LIKE 或 MATCH 操作的查询时需要扫描的数据量。

CREATE TABLE example_table
(
    -- 定义表字段
    id UInt64,
    text_field String,
    ...
    -- 定义 ngrambf_v1 索引
    INDEX ngrambf_text_field_idx text_field TYPE ngrambf_v1(3, 512, 3, 0) GRANULARITY 1
)
ENGINE = MergeTree()
ORDER BY id;

在这个例子中,创建了一个 `ngrambf_v1` 索引 `ngrambf_text_field_idx`,针对 `text_field` 字段。索引参数 `(3, 512, 3, 0)` 表示:
- 使用 3 为 N-gram 的长度。
- 布隆过滤器的大小为 512 位。
- 存储在布隆过滤器中的 N-gram 的最大个数为 3。
- N-gram 的起始位置偏移为 0。

`GRANULARITY 1` 指定了索引的粒度,这里设为 1,表示每个数据块都会被索引。

N-gram: 

        是指从文本中提取的长度为 N 的字符序列。例如,对于字符串 "ClickHouse",其 2-gram(双元组)包括 "Cl"、"li"、"ic"、"ck"、"kH"、"Ho"、"ou"、"us"、"se"。

布隆过滤器:

        是一种概率性数据结构,用于测试一个元素是否在一个集合中。布隆过滤器可以高效地存储和查询数据,但它有一定的误识别率(false positive rate),意味着在某些情况下,布隆过滤器可能会错误地表示一个元素在集合中,尽管实际上它不在。

4.创建带有 `ngrambf_v1` 索引的表的示例

`tokenbf_v1` 索引是 ClickHouse 中的一种数据跳过索引,其设计用于优化文本字段上基于令牌(token)的搜索查询。该索引类型结合了令牌化(tokenization)和布隆过滤器(Bloom filter)技术,以提高执行包含 `LIKE`、`ILIKE`、`IN` 或 `==` 操作的字符串查询时的性能。

CREATE TABLE example_table
(
    -- 定义表字段
    id UInt64,
    text_field String,
    ...
    -- 定义 tokenbf_v1 索引
    INDEX tokenbf_text_field_idx text_field TYPE tokenbf_v1(64, 3, 0) GRANULARITY 1
)
ENGINE = MergeTree()
ORDER BY id;

令牌化:将文本字符串分解成一系列的令牌(tokens),通常是单词或短语。例如,对于字符串 "ClickHouse is fast",其令牌可能是 "ClickHouse"、"is"、"fast"。

在这个例子中,创建了一个 `tokenbf_v1` 索引 `tokenbf_text_field_idx`,针对 `text_field` 字段。索引参数 `(64, 3, 0)` 表示:

- 布隆过滤器的大小为 64 位。
- 存储在布隆过滤器中的令牌的最大个数为 3。
- 令牌的起始位置偏移为 0。

`GRANULARITY 1` 指定了索引的粒度,这里设为 1,表示每个数据块都会生成布隆过滤器。

5.创建投影索引的示例

它允许为表创建一个或多个投影。投影是表的一个子集,可以包含表中的部分列或者通过表达式计算得到的新列,还可能有自己的排序规则(ORDER BY)。投影的目的是优化特定查询,通过物化存储经常查询的列的特定排列或计算结果,以加快这些查询的执行速度。

CREATE TABLE example_table
(
    id UInt64,
    timestamp DateTime,
    value Float64,
    ...
)
ENGINE = MergeTree()
ORDER BY (timestamp, id);

-- 创建一个投影,只包含 id 和 value 列,并按 value 排序
ALTER TABLE example_table ADD PROJECTION projection_name
(
    SELECT id, value
    ORDER BY value
);

在这个例子中,`example_table` 是一个按照 `timestamp` 和 `id` 排序的表。通过 `ALTER TABLE` 语句添加了一个名为 `projection_name` 的投影,它只包含 `id` 和 `value` 这两个列,并且按照 `value` 列的值排序。这意味着,如果常常有基于 `value` 列的查询,ClickHouse 可以利用这个投影来提高这类查询的性能。


创建投影的语法类似于创建表的语法,包括定义列以及指定排序规则。创建投影不会立即生成数据,而是在后续的数据插入、合并或优化操作中逐渐构建的。一旦投影被构建,它就会自动用于适合的查询。


需要注意的是,投影会占用额外的磁盘空间,因为它们物化存储了额外的数据。因此,在决定使用投影时,应当平衡查询性能的提升和额外资源消耗之间的关系。投影索引主要适用于那些有着复杂查询模式和性能要求的场景。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

初学者如何入门 Generative AI 之 Stable Diffusion 与 CLIP :看两篇综述,玩几个应用感受一下先!超多高清大图,沉浸式体验

文章大纲 4种 图片生成 的算法扩散模型的起源Stable DiffusionCLIP参考文献与学习路径A synthography of an astronaut riding a horse created in NightCafe Studio with Stable Diffusion XL (SDXL). Prompt is a photograph of an astronaut riding a horse with weight of …

数据结构与算法-Rust 版读书笔记-1语言入门

数据结构与算法-Rust 版笔记 一、语言入门 1、关键字、注释、命名风格 目前&#xff08;可能还会增加&#xff09;39个&#xff0c;注意&#xff0c;Self和self是两个关键字。 Self enum match super as extern mod trait async false …

【LeetCode热题100】【滑动窗口】无重复字符的最长子串

给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串 的长度。 示例 1: 输入: s "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc"&#xff0c;所以其长度为 3。示例 2: 输入: s "bbbbb" 输出: 1 解释: 因为无…

macos下安装科研绘图软件Origin

科研人必备软件Origin&#xff0c;主要是考虑到很多期刊都要求绘制origin可编辑的图&#xff0c;所以有些时候必须用这个软件&#xff0c;但是这个软件macos并不支持&#xff0c;所以必须考虑其他的方案&#xff0c;我没有安装虚拟机&#xff0c;而是使用crossover 安装crosso…

程序的机器代码表示--函数调用

call和ret指令 如何访问栈帧、如何切换栈帧、如何传递参数和返回值 call、ret指令作用&#xff1a; call&#xff1a;1&#xff09;将IP&#xff08;即PC&#xff09;旧值压栈保存&#xff08;保存在函数的栈帧顶部&#xff09;&#xff1b;2&#xff09;设置IP新值&#xff0…

P1317 低洼地题解

题目 一组数&#xff0c;分别表示地平线的高度变化。高度值为整数&#xff0c;相邻高度用直线连接。找出并统计有多少个可能积水的低洼地&#xff1f; 如图&#xff1a;地高变化为 [0,1,0,2,1,2,0,0,2,0]。 输入输出格式 输入格式 两行&#xff0c;第一行n, 表示有n个数。第…

改进的A*算法的路径规划(1)

引言 近年来&#xff0c;随着智能时代的到来&#xff0c;路径规划技术飞快发展&#xff0c;已经形成了一套较为 成熟的理论体系。其经典规划算法包括 Dijkstra 算法、A*算法、D*算法、Field D* 算法等&#xff0c;然而传统的路径规划算法在复杂的场景的表现并不如人意&#xff…

【动态规划】斐波那契数列模型_解码方法_C++(medium)

题目链接&#xff1a;leetcode解码方法 目录 题目解析&#xff1a; 算法原理 1.状态表示 2.状态转移方程 3.初始化 4.填表顺序 5.返回值 编写代码 题目解析&#xff1a; 题目让我们求解码 方法的 总数 由题可得&#xff1a; 0和有前导0&#xff08;比如06、08、04&am…

(企业项目)微服务项目解决跨域问题:

前后端分离项目中前端出现了跨域的问题 在网关模块配置文件中添加 配置 application.properties # 允许请求来源&#xff08;老版本叫allowedOrigin&#xff09; spring.cloud.gateway.globalcors.cors-configurations.[/**].allowedOriginPatterns* # 允许携带的头信息 spri…

vue 实现返回顶部功能-指定盒子滚动区域

vue 实现返回顶部功能-指定盒子滚动区域 html代码css代码返回顶部显示/隐藏返回标志 html代码 <a-icontype"vertical-align-top"class"top"name"back-top"click"backTop"v-if"btnFlag"/>css代码 .top {height: 35px;…

RabbitMQ学习笔记10 综合实战 实现新商家规定时间内上架商品检查

配置文件&#xff1a; 记住添加这个。 加上这段代码&#xff0c;可以自动创建队列和交换机以及绑定关系。 我们看到了我们创建的死信交换机和普通队列。 我们可以看到我们队列下面绑定的交换机。 我们创建一个controller包进行测试: 启动&#xff1a; 过一段时间会变成死信队列…

JVM虚拟机系统性学习-类加载子系统

类加载子系统 类加载的时机 类加载的时机主要有 4 个&#xff1a; 遇到 new、getstatic、putstatic、invokestatic 这四条字节码指令时&#xff0c;如果对应的类没有初始化&#xff0c;则要先进行初始化 new 关键字创建对象时读取或设置一个类型的静态字段时&#xff08;被 …

FastAPI请求体-多个参数

路径参数、查询参数&#xff0c;和请求体混合 首先&#xff0c;我们需要导入所需的库。我们将使用FastAPI、Path和Annotated来处理路由和参数&#xff0c;并使用BaseModel和Union来自定义数据模型。 完整示例代码 from typing import Annotated, Unionfrom fastapi import F…

开源好用EasyImages简单图床源码

源码介绍 开源好用EasyImages简单图床源码分享&#xff0c;虽然它是开源程序&#xff0c;但功能一点也不弱&#xff0c;不仅支持多文件上传、文字/图片水印、支持API和鉴黄、还能自定义代码&#xff0c;最重要的是它不强制使用数据库运行&#xff0c;这就给我们的部署和维护带…

算法训练营Day7

语言 采用的Java语言&#xff0c;一些分析也是用于Java&#xff0c;请注意。 454.四数相加II 454. 四数相加 II - 力扣&#xff08;LeetCode&#xff09; 这道题理解好只是统计数量即可&#xff0c;不需要去重&#xff0c;因此很简单的题目。 class Solution {public int fou…

SSD基础架构与NAND IO并发问题探讨

在我们的日常生活中&#xff0c;我们经常会遇到一些“快如闪电”的事物&#xff1a;比如那场突如其来的雨、那个突然出现在你眼前的前任、还有就是今天我们要聊的——固态硬盘&#xff08;SSD&#xff09;。 如果你是一个技术宅&#xff0c;或者对速度有着近乎偏执的追求&…

深度学习——第4.1章 深度学习的数学基础

第4章 深度学习的数学基础 目录 4.1 向量 4.2 求和符号 4.3 累乘符号 4.4 导数 4.5 偏导数 4.6 矩阵 4.7 指数函数和对数函数 注意&#xff1a;4.6和4.7位于4.2章 第4章 深度学习的数学基础 本章总结一下机器学习所需的数学知识&#xff0c;同时介绍如何在Python中使用…

Kafka 最佳实践:构建可靠、高性能的分布式消息系统

Apache Kafka 是一个强大的分布式消息系统&#xff0c;被广泛应用于实时数据流处理和事件驱动架构。为了充分发挥 Kafka 的优势&#xff0c;需要遵循一些最佳实践&#xff0c;确保系统在高负载下稳定运行&#xff0c;数据可靠传递。本文将深入探讨 Kafka 的一些最佳实践&#x…

二叉排序树的判断(二叉树的顺序存储):2022年408算法题

对于采用顺序存储方式保存的二叉树&#xff0c;根结点保存在SqBiTNode[0]中&#xff1b;当某结点保存SqBiTNode[i]中时&#xff0c;若有左孩子&#xff0c;则其值保存在SqBiTNode [2i1]中&#xff1b;若有右孩子&#xff0c;则其值保存在SqBiTNode[2i2]中&#xff1b;若有双亲结…

JavaScript中冷门但有用的String.raw

文章梗概 本文讲解的String.raw&#xff0c;作为JavaScript中的静态方法&#xff0c;用来获取模板字符串的原始字符串形式&#xff0c;需要注意的是与字符串模板搭配时候的事项。 介绍 String.raw() 静态方法是模板字符串的标签函数。它的作用类似于 Python 中的 r 前缀或 C#…