我是靠谱客的博主 靓丽蓝天,最近开发中收集的这篇文章主要介绍ClickHouse,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

列式数据库。OLAP。联机分析处理。

https://clickhouse.com/docs/en/intro/

快速上手

OLAP场景的关键特征:

  • 绝大多数是读请求
  • 数据以相当大的批次(> 1000行)更新,而不是单行更新;或者根本没有更新。
  • 已添加到数据库的数据不能修改。
  • 对于读取,从数据库中提取相当多的行,但只提取列的一小部分。
  • 宽表,即每个表包含着大量的列
  • 查询相对较少(通常每台服务器每秒查询数百次或更少)
  • 对于简单查询,允许延迟大约50毫秒
  • 列中的数据相对较小:数字和短字符串(例如,每个URL 60个字节)
  • 处理单个查询时需要高吞吐量(每台服务器每秒可达数十亿行)
  • 事务不是必须的
  • 对数据一致性要求低
  • 每个查询有一个大表。除了他以外,其他的都很小。
  • 查询结果明显小于源数据。换句话说,数据经过过滤或聚合,因此结果适合于单个服务器的RAM中

很容易可以看出,OLAP场景与其他通常业务场景(例如,OLTP或K/V)有很大的不同, 因此想要使用OLTP或Key-Value数据库去高效的处理分析查询场景,并不是非常完美的适用方案。例如,使用OLAP数据库去处理分析请求通常要优于使用MongoDB或Redis去处理分析请求。

列式数据库更适合OLAP场景的原因

  • 输入输出:

    • 针对分析类查询,通常只需要读取表的一小部分列。在列式数据库中你可以只读取你需要的数据。

    • 由于数据总是打包成批量读取的,所以压缩是非常容易的。同时数据按列分别存储也更容易压缩。这进一步降低了IO的体积。

    • 由于IO的降低,这将帮助更多的数据被系统缓存

      例如,查询«统计每个广告平台的记录数量»需要读取«广告平台ID»这一列,它在未压缩的情况下需要1个字节进行存储。如果大部分流量不是来自广告平台,那么这一列至少可以以十倍的压缩率被压缩。当采用快速压缩算法,它的解压速度最少在十亿字节(未压缩数据)每秒。换句话说,这个查询可以在单个服务器上以每秒大约几十亿行的速度进行处理。这实际上是当前实现的速度。

  • CPU:由于执行一个查询需要处理大量的行,因此在整个向量上执行所有操作比在每一行上执行所有操作更加高效。同时这将有助于实现一个几乎没有调用成本的查询引擎。所以,在数据按列存储并且按列执行是很有意义的。

    有两种方法可以做到这一点:

    1. 向量引擎:所有的操作都是为向量而不是为单个值编写的。这意味着多个操作之间的不再需要频繁的调用,并且调用的成本基本可以忽略不计。操作代码包含一个优化的内部循环。
    2. 代码生成:生成一段代码,包含查询中的所有操作。

简介

真正的列式数据库管理系统

必须支持固定长度数值类型。

解压缩的速度主要取决于未压缩数据的大小。

数据压缩

除了在磁盘空间和CPU消耗之间进行不同权衡的高效通用压缩编解码器之外,ClickHouse还提供针对特定类型数据的专用编解码器,这使得ClickHouse能够与更小的数据库(如时间序列数据库)竞争并超越它们。

数据的磁盘存储

ClickHouse被设计用于工作在传统磁盘上的系统,它提供每GB更低的存储成本,但如果可以使用SSD和内存,它也会合理地利用这些资源。

多核心并行处理

clickhouse会使用服务器上一切可用的资源,从而以最自然的方式并行处理大型查询。

多服务器分布式处理

在clickhouse中,数据可以保存在不同的shard上,每一个shard都由一组用于容错的replica组成,查询可以并行地在所有shard上进行处理。这些对用户来说是透明的。

支持SQL

向量引擎

为了高效的使用CPU,数据不仅仅按列存储,同时还按向量(列的一部分)进行处理,这样可以更加高效地使用CPU。

实时数据更新

支持在表中定义主键。为了使查询能够快速在主键中进行范围查找,数据总是以增量地方式有序地存储在MergeTree中。

因此,数据可以持续不断地高效地写入到表中,并且写入过程中不会存在任何锁地行为。

索引

按照主键对数据进行排序,这将帮助ClickHouse在几十毫秒以内完成对数据特定值或范围地查找。

适合在线查询

在线查询意味着在没有对数据做任何预处理地情况下,以极低地延迟处理查询并将结果加载到用户的页面中。

支持近似计算

提供各种各样在允许牺牲数据精度的情况下对查询进行加速的方法:

  • 用于近似计算的各类聚合函数,例如:distinct values,medians,quantiles
  • 基于数据的部分样本进行近似查询。这时,仅会从磁盘检索少部分比例的数据。
  • 不使用全部的聚合条件,通过随机选择有限个数据聚合条件进行聚合。这在数据聚合条件满足某些分布的条件下,在提供相当准确的聚合结果的同时降低了计算资源的使用。

自适应Join算法

支持自定义Join多个表,它更倾向于散列连接算法,如果有个大表,则使用合并-连接算法。

支持数据复制和数据完整性

使用异步的多主复制技术。当数据被写入任何一个可用副本后,系统会在后台将数据分发给其他副本,以保证系统在不同副本上保持相同的数据。在大多数情况下ClickHouse能在故障后自动恢复,在一些少数的复杂情况下需要手动恢复。

角色的访问控制

使用SQL查询实现用户账户管理,并允许角色的访问控制。

限制及不足

  • 没有完整的事务支持
  • 缺少高频率、低延迟的修改或删除已存在数据的能力。仅能用于批量删除或修改数据,但这符合GDPR。
  • 稀疏索引使得CK不适合其键检索单行的点查。即不适合点查。

单个大查询的吞吐量

吞吐量可以使用每秒处理的行数或每秒处理的字节数来衡量。

如果数据被放置在page cache中,则一个不太复杂的查询在单个服务器上大约能够以2-10GB/s(未压缩)的速度进行处理。

如果数据没有放置在page cache中,则速度取决于磁盘系统和数据的压缩率。

例如磁盘400MB/S,数据压缩率是3,那么数据的处理速度是1.2GB/s。

对于分布式处理,处理速度几乎是线性扩展的,但这受限于聚合或排序的结果不是那么大的情况下。

处理短查询的延迟时间

如果一个查询使用主键并且没有太多行(几十万)进行处理,并且没有查询太多的列,那么在数据被page cache缓存的情况下,它的延迟应该小于50毫秒(在最佳的情况下应该小于10毫秒)。 否则,延迟取决于数据的查找次数。如果你当前使用的是HDD,在数据没有加载的情况下,查询所需要的延迟可以通过以下公式计算得知: 查找时间(10 ms) * 查询的列的数量 * 查询的数据块的数量。

处理大量短查询的吞吐量

在相同的情况下,ClickHouse可以在单个服务器上每秒处理数百个查询(在最佳的情况下最多可以处理数千个)。但是由于这不适用于分析型场景。因此我们建议每秒最多查询100次。

数据的写入性能

每次写入不少于1000行的批量写入,或每秒不超过一个写入请求。

当使用tab-separated格式将一份数据写入到 MergeTree表中时,写入速度大约为50到200MB/s。如果您写入的数据每行为1Kb,那么写入速度为5W到20W行每秒。

如果您的行更小,那么写入速度将会更高。为了提高写入性能,您可以使用多个INSERT进行并行写入,这将带来线性的提升。

接口

命令行客户端

CK提供了原生的命令行客户端clickhouse-client

不同的客户端和服务器版本彼此兼容,但是一些特性可能在旧客户机中不可用。

我们建议使用与服务器应用相同版本的客户端。

使用方式

客户端可以在交互和非交互(批处理)模式下使用。要使用批处理模式,请指定query参数,或将数据发送到stdin(它会验证stdin是否是终端),或两者同时进行。与HTTP接口类似,当使用query参数并向stdin发送数据时,客户端请求就是一行一行的stdin输入作为query的参数。这种方式在大规模的插入请求中非常 方便。

echo -ne "1, 'some text', '2016-'" | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV"
cat <<_EOF | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";
3, 'some text', '2016-08-14 00:00:00'
4, 'some more text', '2016-08-14 00:00:01'
_EOF
cat file.csv | clickhouse-client --database=test --query="INSERT INTO test FORMAT CSV";

在批处理模式中,默认的数据格式是TabSeparated分隔的。您可以根据查询来灵活设置FORMAT格式。

默认情况下,在批量模式中只能执行单个查询。为了从一个Script中执行多个查询,可以使用--multiquery参数。除了INSERT请求外,这种方式在任何地方都有用。查询的结果会连续且不含分隔符地输出。 同样的,为了执行大规模的查询,您可以为每个查询执行一次clickhouse-client。但注意到每次启动clickhouse-client程序都需要消耗几十毫秒时间。

在交互模式下,每条查询过后,你可以直接输入下一条查询命令。

如果multiline没有指定(默认没指定):为了执行查询,按下Enter即可。查询语句不是必须使用分号结尾。如果需要写一个多行的查询语句,可以在换行之前输入一个反斜杠,然后在您按下Enter键后,您就可以输入当前语句的下一行查询了。

如果指定了multiline:为了执行查询,需要以分号结尾并且按下Enter键。如果行末没有分号,将认为当前语句并没有输入完而要求继续输入下一行。

您可以指定G来替代分号或者在分号后面,这表示使用Vertical的格式。在这种格式下,每一个值都会打印在不同的行中,这种方式对于宽表来说很方便。这个不常见的特性是为了兼容MySQL命令而加的。

命令行客户端是基于replxx(类似于readline)。换句话说,它可以使用我们熟悉的快捷键方式来操作以及保留历史命令。 历史命令会写入在~/.clickhouse-client-history中。

默认情况下,输出的格式是PrettyCompact。您可以通过FORMAT设置根据不同查询来修改格式,或者通过在查询末尾指定G字符,或通过在命令行中使用--format--vertical参数,或使用客户端的配置文件

若要退出客户端,使用Ctrl+D(或Ctrl+C),或者输入以下其中一个命令:exit, quit, logout, учше, йгше, дщпщге, exit;, quit;, logout;, q, Q, :q

当执行一个查询的时候,客户端会显示:

  1. 进度, 进度会每秒更新十次(默认情况下)。对于很快的查询,进度可能没有时间显示。
  2. 为了调试会显示解析且格式化后的查询语句。
  3. 指定格式的输出结果。
  4. 输出结果的行数的行数,经过的时间,以及查询处理的速度。

命令行客户端允许通过外部数据(外部临时表)来查询。更多相关信息,请参考 «外部数据查询处理».

查询参数

您可以创建带有参数的查询,并将值从客户端传递给服务器。这允许避免在客户端使用特定的动态值格式化查询,例如:

clickhouse-client --param_parName="[1, 2]"
-q "SELECT * FROM table WHERE a = {parName:Array(UInt16)}"

语法:像平常一样格式化一个查询,然后把你想要从app参数传递到查询的值用大括号格式化,格式如下:

{<name>:<data type>}
  • name — 占位符标识符。在控制台客户端,使用--param_<name> = value来指定
  • data type — 数据类型参数值。例如,一个数据结构(integer, ('string', integer))拥有Tuple(UInt8, Tuple(String, UInt8))数据类型

配置

您可以通过以下方式传入参数到clickhouse-client中(所有的参数都有默认值):

  • 通过命令行

    命令行参数会覆盖默认值和配置文件的配置。

  • 配置文件

    配置文件的配置会覆盖默认值

命令行参数:

  • --host, -h -– 服务端的host名称, 默认是localhost。您可以选择使用host名称或者IPv4或IPv6地址。
  • --port – 连接的端口,默认值:9000。注意HTTP接口以及TCP原生接口使用的是不同端口。
  • --user, -u – 用户名。 默认值:default
  • --password – 密码。 默认值:空字符串。
  • --query, -q – 使用非交互模式查询。
  • --database, -d – 默认当前操作的数据库. 默认值:服务端默认的配置(默认是default)。
  • --multiline, -m – 如果指定,允许多行语句查询(Enter仅代表换行,不代表查询语句完结)。
  • --multiquery, -n – 如果指定, 允许处理用;号分隔的多个查询,只在非交互模式下生效。
  • --format, -f – 使用指定的默认格式输出结果。
  • --vertical, -E – 如果指定,默认情况下使用垂直格式输出结果。这与–format=Vertical相同。在这种格式中,每个值都在单独的行上打印,这种方式对显示宽表很有帮助。
  • --time, -t – 如果指定,非交互模式下会打印查询执行的时间到stderr中。
  • --stacktrace – 如果指定,如果出现异常,会打印堆栈跟踪信息。
  • --config-file – 配置文件的名称。
  • --secure – 如果指定,将通过安全连接连接到服务器。
  • --history_file — 存放命令历史的文件的路径。
  • --param_<name> — 查询参数配置查询参数.

配置文件

clickhouse-client使用以下第一个配置文件:

  • 通过--config-file参数指定。
  • ./clickhouse-client.xml
  • ~/.clickhouse-client/config.xml
  • /etc/clickhouse-client/config.xml

配置文件示例:

<config>
<user>username</user>
<password>password</password>
<secure>False</secure>
</config>

输入输出格式

支持:CSV、JSON、ORC、PROTOBUF

可以使用的库

https://github.com/ClickHouse/clickhouse-cpp

https://github.com/ClickHouse/clickhouse-jdbc

引擎

数据库引擎允许您处理数据表。默认情况下,CK使用Atomic数据库引擎。它提供了可配置的table enginesSQL dialect

Atomic

它支持非阻塞的DROP TABLE和RENAME TABLE查询和原子的EXCHANGE TABLES t1 AND t2查询。默认情况下使用Atomic数据库引擎。

使用方式

Table UUID

数据库Atomic中的所有表都有唯一的UUID,并将数据存储在目录/clickhouse_path/store/xxx/xxxyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy/,其中xxxyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy是该表的UUID。

通常,UUID是自动生成的,但用户也可以在创建表时以相同的方式显式指定UUID(不建议这样做)。可以使用 show_table_uuid_in_table_create_query_if_not_nil设置。显示UUID的使用SHOW CREATE查询。例如:

CREATE TABLE name UUID '28f1c61c-2970-457a-bffe-454156ddcfef' (n UInt64) ENGINE = ...;

RENAME TABLES

RENAME查询是在不更改UUID和移动表数据的情况下执行的。这些查询不会等待使用表的查询完成,而是会立即执行。

DROP/DETACH TABLES

DROP TABLE上,不删除任何数据,数据库Atomic只是通过将元数据移动到/clickhouse_path/metadata_dropped/将表标记为已删除,并通知后台线程。最终表数据删除前的延迟由database_atomic_delay_before_drop_table_sec设置指定。

可以使用SYNC修饰符指定同步模式。使用database_atomic_wait_for_drop_and_detach_synchronously设置执行此操作。在本例中,DROP等待运行 SELECT, INSERT和其他使用表完成的查询。表在不使用时将被实际删除。

EXCHANGE TABLES

EXCHANGE以原子方式交换表。

EXCHANGE TABLES new_table AND old_table;

ReplicatedMergeTree in Atomic Db

对于ReplicatedMergeTree表,建议不要在ZooKeeper和副本名称中指定engine-path的参数。在这种情况下,将使用配置的参数default_replica_path和default_replica_name。如果要显式指定引擎的参数,建议使用{uuid}宏。这是非常有用的,以便为ZooKeeper中的每个表自动生成唯一的路径。

表引擎

表引擎即表的类型,决定了:

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

引擎类型

MergeTree

适用于高负载任务的最通用和功能最强大的表引擎。这些引擎的共同特点是可以快速插入数据并进行后续的后台数据处理。

MergeTree系列引擎支持数据复制(使用Replicated*的引擎版本),分区和一些其他引擎不支持的其他功能。

该类型的引擎:

  • MergeTree
  • ReplacingMergeTree
  • SummingMergeTree
  • AggregatingMergeTree
  • CollapsingMergeTree
  • VersionedCollapsingMergeTree
  • GraphiteMergeTree

日志

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

该类型的引擎:

  • TinyLog
  • StripeLog
  • Log

集成引擎

用于与其他的数据存储与处理系统集成的引擎。 该类型的引擎:

  • Kafka
  • MySQL
  • ODBC
  • JDBC
  • HDFS

用于其他特定功能的引擎

该类型的引擎:

  • Distributed
  • MaterializedView
  • Dictionary
  • Merge
  • File
  • Null
  • Set
  • Join
  • URL
  • View
  • Memory
  • Buffer

虚拟列

虚拟列是表引擎组成的一部分,它在对应的表引擎的源代码中定义。

您不能在 CREATE TABLE 中指定虚拟列,并且虚拟列不会包含在 SHOW CREATE TABLEDESCRIBE TABLE 的查询结果中。虚拟列是只读的,所以您不能向虚拟列中写入数据。

如果想要查询虚拟列中的数据,您必须在SELECT查询中包含虚拟列的名字。SELECT * 不会返回虚拟列的内容。

若您创建的表中有一列与虚拟列的名字相同,那么虚拟列将不能再被访问。我们不建议您这样做。为了避免这种列名的冲突,虚拟列的名字一般都以下划线开头。

MergeTree

MergeTree系列的引擎被设计用于插入极大量的数据到一张表当中。数据可以以数据片段的形式一个接着一个的快速写入,数据片段在后台按照一定的规则进行合并。相比在插入时不断修改已存储的数据,这种策略会高效很多。

主要特点:

  • 存储的数据按照主键排序。这使得您能够创建一个小型的稀疏索引来加快数据检索。
  • 如果指定了分区键,可以使用分区。在相同数据集和相同结果集的情况下 ClickHouse 中某些带分区的操作会比普通操作更快。查询中指定了分区键时 ClickHouse 会自动截取分区数据。这也有效增加了查询性能。
  • 支持数据副本。ReplicatedMergeTree 系列的表提供了数据副本功能。
  • 支持数据采样。需要的话,您可以给表设置一个采样方法。

建表:

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2],
...
INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
ORDER BY expr
[PARTITION BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
[SETTINGS name=value, ...]
  • ORDER BY — 排序键。可以是一组列的元组或任意的表达式。 例如: ORDER BY (CounterID, EventDate) 。如果没有使用 PRIMARY KEY 显式指定的主键,ClickHouse 会使用排序键作为主键。如果不需要排序,可以使用 ORDER BY tuple().

  • PARTITION BY — 分区键 ,可选项。大多数情况下,不需要分使用区键。即使需要使用,也不需要使用比月更细粒度的分区键。分区不会加快查询(这与 ORDER BY 表达式不同)。永远也别使用过细粒度的分区键。不要使用客户端指定分区标识符或分区字段名称来对数据进行分区(而是将分区字段标识或名称作为 ORDER BY 表达式的第一列来指定分区)。

  • TTL - 指定行存储的持续时间并定义数据片段在硬盘和卷上的移动逻辑的规则列表,可选项。

    表达式中必须存在至少一个 DateDateTime 类型的列,比如:

    TTL date + INTERVAl 1 DAY
    

    规则的类型 DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'指定了当满足条件(到达指定时间)时所要执行的动作:移除过期的行,还是将数据片段(如果数据片段中的所有行都满足表达式的话)移动到指定的磁盘(TO DISK 'xxx') 或 卷(TO VOLUME 'xxx')。默认的规则是移除(DELETE)。可以在列表中指定多个规则,但最多只能有一个DELETE的规则。

  • SETTINGS — 控制 MergeTree 行为的额外参数,可选项:

    • index_granularity — 索引粒度。索引中相邻的『标记』间的数据行数。默认值8192 。参考数据存储。

    • index_granularity_bytes — 索引粒度,以字节为单位,默认值: 10Mb。如果想要仅按数据行数限制索引粒度, 请设置为0(不建议)。

    • min_index_granularity_bytes - 允许的最小数据粒度,默认值:1024b。该选项用于防止误操作,添加了一个非常低索引粒度的表。参考数据存储

    • enable_mixed_granularity_parts — 是否启用通过 index_granularity_bytes 控制索引粒度的大小。在19.11版本之前, 只有 index_granularity 配置能够用于限制索引粒度的大小。当从具有很大的行(几十上百兆字节)的表中查询数据时候,index_granularity_bytes 配置能够提升ClickHouse的性能。如果您的表里有很大的行,可以开启这项配置来提升SELECT 查询的性能。

    • use_minimalistic_part_header_in_zookeeper — ZooKeeper中数据片段存储方式 。如果use_minimalistic_part_header_in_zookeeper=1 ,ZooKeeper 会存储更少的数据。更多信息参考[服务配置参数](Server Settings | ClickHouse Documentation)这章中的 设置描述 。

    • in_merge_bytes_to_use_direct_io — 使用直接 I/O 来操作磁盘的合并操作时要求的最小数据量。合并数据片段时,ClickHouse 会计算要被合并的所有数据的总存储空间。如果大小超过了 min_merge_bytes_to_use_direct_io 设置的字节数,则 ClickHouse 将使用直接 I/O 接口(O_DIRECT 选项)对磁盘读写。如果设置 min_merge_bytes_to_use_direct_io = 0 ,则会禁用直接 I/O。默认值:10 * 1024 * 1024 * 1024 字节。

      <a name="mergetree_setting-merge_with_ttl_timeout"></a>
      
    • merge_with_ttl_timeout — TTL合并频率的最小间隔时间,单位:秒。默认值: 86400 (1 天)。

    • write_final_mark — 是否启用在数据片段尾部写入最终索引标记。默认值: 1(不要关闭)。

    • merge_max_block_size — 在块中进行合并操作时的最大行数限制。默认值:8192

    • storage_policy — 存储策略。 参见 使用具有多个块的设备进行数据存储.

    • min_bytes_for_wide_part,min_rows_for_wide_part 在数据片段中可以使用Wide格式进行存储的最小字节数/行数。您可以不设置、只设置一个,或全都设置。参考:数据存储

    • max_parts_in_total - 所有分区中最大块的数量(意义不明)

    • max_compress_block_size - 在数据压缩写入表前,未压缩数据块的最大大小。您可以在全局设置中设置该值(参见max_compress_block_size)。建表时指定该值会覆盖全局设置。

    • min_compress_block_size - 在数据压缩写入表前,未压缩数据块的最小大小。您可以在全局设置中设置该值(参见min_compress_block_size)。建表时指定该值会覆盖全局设置。

    • max_partitions_to_read - 一次查询中可访问的分区最大数。您可以在全局设置中设置该值(参见max_partitions_to_read)。

ENGINE MergeTree() PARTITION BY toYYYYMM(EventDate) ORDER BY (CounterID, EventDate, intHash32(UserID)) SAMPLE BY intHash32(UserID) SETTINGS index_granularity=8192

数据存储

表由按主键排序的数据片段组成。

不同分区的数据会被分称不同的片段,CK在后台合并数据片段以便更高效地存储。不同分区的数据片段不会进行合并。合并机制并不保证具有相同主键的行全都合并到同一个数据片段中。

数据片段可以以 WideCompact 格式存储。在 Wide 格式下,每一列都会在文件系统中存储为单独的文件,在 Compact 格式下所有列都存储在一个文件中。Compact 格式可以提高插入量少插入频率频繁时的性能。

数据存储格式由 min_bytes_for_wide_partmin_rows_for_wide_part 表引擎参数控制。如果数据片段中的字节数或行数少于相应的设置值,数据片段会以 Compact 格式存储,否则会以 Wide 格式存储。

每个数据片段被逻辑的分割成颗粒(granules)。颗粒是 ClickHouse 中进行数据查询时的最小不可分割数据集。ClickHouse 不会对行或值进行拆分,所以每个颗粒总是包含整数个行。每个颗粒的第一行通过该行的主键值进行标记, ClickHouse 会为每个数据片段创建一个索引文件来存储这些标记。对于每列,无论它是否包含在主键当中,ClickHouse 都会存储类似标记。这些标记让您可以在列文件中直接找到数据。

颗粒的大小通过表引擎参数 index_granularityindex_granularity_bytes 控制。颗粒的行数的在 [1, index_granularity] 范围中,这取决于行的大小。如果单行的大小超过了 index_granularity_bytes 设置的值,那么一个颗粒的大小会超过 index_granularity_bytes。在这种情况下,颗粒的大小等于该行的大小。

主键和索引在查询中的表现

稀疏索引会引起额外的数据读取。当读取主键单个区间范围的数据时,每个数据块中最多会多读 index_granularity * 2 行额外的数据。(读取稀疏索引前面与后面的块)

稀疏索引使得您可以处理极大量的行,因为大多数情况下,这些索引常驻于内存。

ClickHouse 不要求主键唯一,所以您可以插入多条具有相同主键的行。

您可以在PRIMARY KEYORDER BY条件中使用可为空的类型的表达式,但强烈建议不要这么做。为了启用这项功能,请打开allow_nullable_key,NULLS_LAST规则也适用于ORDER BY条件中有NULL值的情况下。

主键的选择

主键中列的数量并没有明确的限制。依据数据结构,您可以在主键包含多些或少些列。这样可以:

  • 改善索引的性能。

  • 如果当前主键是 (a, b) ,在下列情况下添加另一个 c 列会提升性能:

  • 查询会使用 c 列作为条件

  • 很长的数据范围( index_granularity 的数倍)里 (a, b) 都是相同的值,并且这样的情况很普遍。换言之,就是加入另一列后,可以让您的查询略过很长的数据范围。

  • 改善数据压缩。

    ClickHouse 以主键排序片段数据,所以,数据的一致性越高,压缩越好。

  • 在CollapsingMergeTree 和 SummingMergeTree 引擎里进行数据合并时会提供额外的处理逻辑。

    在这种情况下,指定与主键不同的 排序键 也是有意义的。

长的主键会对插入性能和内存消耗有负面影响,但主键中额外的列并不影响 SELECT 查询的性能。

可以使用 ORDER BY tuple() 语法创建没有主键的表。在这种情况下 ClickHouse 根据数据插入的顺序存储。如果在使用 INSERT ... SELECT 时希望保持数据的排序,请设置 max_insert_threads = 1。

想要根据初始顺序进行数据查询,使用 单线程查询

选择与排序键不同的主键

Clickhouse可以做到指定一个跟排序键不一样的主键,此时排序键用于在数据片段中进行排序,主键用于在索引文件中进行标记的写入。这种情况下,主键表达式元组必须是排序键表达式元组的前缀(即主键为(a,b),排序列必须为(a,b,**))。

当使用 SummingMergeTree 和 AggregatingMergeTree 引擎时,这个特性非常有用。通常在使用这类引擎时,表里的列分两种:维度度量 。典型的查询会通过任意的 GROUP BY 对度量列进行聚合并通过维度列进行过滤。由于 SummingMergeTree 和 AggregatingMergeTree 会对排序键相同的行进行聚合,所以把所有的维度放进排序键是很自然的做法。但这将导致排序键中包含大量的列,并且排序键会伴随着新添加的维度不断的更新。

在这种情况下合理的做法是,只保留少量的列在主键当中用于提升扫描效率,将维度列添加到排序键中。

对排序键进行 ALTER 是轻量级的操作,因为当一个新列同时被加入到表里和排序键里时,已存在的数据片段并不需要修改。由于旧的排序键是新排序键的前缀,并且新添加的列中没有数据,因此在表修改时的数据对于新旧的排序键来说都是有序的。

索引和分区在查询中的应用

对于 SELECT 查询,ClickHouse 分析是否可以使用索引。如果 WHERE/PREWHERE 子句具有下面这些表达式(作为完整WHERE条件的一部分或全部)则可以使用索引:进行相等/不相等的比较;对主键列或分区列进行IN运算、有固定前缀的LIKE运算(如name like ‘test%’)、函数运算(部分函数适用),还有对上述表达式进行逻辑运算。

因此,在索引键的一个或多个区间上快速地执行查询是可能的。下面例子中,指定标签;指定标签和日期范围;指定标签和日期;指定多个标签和日期范围等执行查询,都会非常快。

要检查 ClickHouse 执行一个查询时能否使用索引,可设置 force_index_by_date 和 force_primary_key 。

使用按月分区的分区列允许只读取包含适当日期区间的数据块,这种情况下,数据块会包含很多天(最多整月)的数据。在块中,数据按主键排序,主键第一列可能不包含日期。因此,仅使用日期而没有用主键字段作为条件的查询将会导致需要读取超过这个指定日期以外的数据。

部分单调主键的使用

跳数索引

*MergeTree 系列的表可以指定跳数索引。 跳数索引是指数据片段按照粒度(建表时指定的index_granularity)分割成小块后,将上述SQL的granularity_value数量的小块组合成一个大的块,对这些大块写入索引信息,这样有助于使用where筛选时跳过大量不必要的数据,减少SELECT需要读取的数据量。(对于主键索引的索引!)

CREATE TABLE table_name
(
u64 UInt64,
i32 Int32,
s String,
...
INDEX a (u64 * i32, s) TYPE minmax GRANULARITY 3,
INDEX b (u64 * length(s)) TYPE set(1000) GRANULARITY 4
) ENGINE = MergeTree()
...

可用的索引类型

  • minmax 存储指定表达式的极值(如果表达式是 tuple ,则存储 tuple 中每个元素的极值),这些信息用于跳过数据块,类似主键。

  • set(max_rows) 存储指定表达式的不重复值(不超过 max_rows 个,max_rows=0 则表示『无限制』)。这些信息可用于检查数据块是否满足 WHERE 条件。

  • ngrambf_v1(n, size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed) 存储一个包含数据块中所有 n元短语(ngram) 的 布隆过滤器 。只可用在字符串上。 可用于优化 equalslikein 表达式的性能。

    • n – 短语长度。
    • size_of_bloom_filter_in_bytes – 布隆过滤器大小,字节为单位。(因为压缩得好,可以指定比较大的值,如 256 或 512)。
    • number_of_hash_functions – 布隆过滤器中使用的哈希函数的个数。
    • random_seed – 哈希函数的随机种子。
  • tokenbf_v1(size_of_bloom_filter_in_bytes, number_of_hash_functions, random_seed)ngrambf_v1 类似,但是存储的是token而不是ngrams。Token是由非字母数字的符号分割的序列。

  • bloom_filter(bloom_filter([false_positive]) – 为指定的列存储布隆过滤器

    可选参数false_positive用来指定从布隆过滤器收到错误响应的几率。取值范围是 (0,1),默认值:0.025

    支持的数据类型:Int*, UInt*, Float*, Enum, Date, DateTime, String, FixedString, Array, LowCardinality, Nullable

函数支持

WHERE 子句中的条件可以包含对某列数据进行运算的函数表达式,如果列是索引的一部分,ClickHouse会在执行函数时尝试使用索引。不同的函数对索引的支持是不同的。

列和表的TTL

TTL date_time + INTERVAL 1 MONTH
TTL date_time + INTERVAL 15 HOUR
CREATE TABLE example_table
(
d DateTime,
a Int TTL d + INTERVAL 1 MONTH,
b Int TTL d + INTERVAL 1 MONTH,
c String
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d;
CREATE TABLE example_table
(
d DateTime,
a Int
)
ENGINE = MergeTree
PARTITION BY toYYYYMM(d)
ORDER BY d
TTL d + INTERVAL 1 MONTH [DELETE],
d + INTERVAL 1 WEEK TO VOLUME 'aaa',
d + INTERVAL 2 WEEK TO DISK 'bbb';

使用多个块设备进行数据存储

MergeTree 系列表引擎可以将数据存储在多个块设备上。这对某些可以潜在被划分为“冷”“热”的表来说是很有用的。最新数据被定期的查询但只需要很小的空间。相反,详尽的历史数据很少被用到。如果有多块磁盘可用,那么“热”的数据可以放置在快速的磁盘上(比如 NVMe 固态硬盘或内存),“冷”的数据可以放在相对较慢的磁盘上(比如机械硬盘)。

数据片段是 MergeTree 引擎表的最小可移动单元。属于同一个数据片段的数据被存储在同一块磁盘上。数据片段会在后台自动的在磁盘间移动,也可以通过 ALTER 查询来移动。

虚拟列

  • _part - 分区名称。
  • _part_index - 作为请求的结果,按顺序排列的分区数。
  • _partition_id — 分区名称。
  • _part_uuid - 唯一部分标识符(如果 MergeTree 设置assign_part_uuids 已启用)。
  • _partition_valuepartition by 表达式的值(元组)。
  • _sample_factor - 采样因子(来自请求)。

SQL参考

SELECT

WITH子句

提供公共表达式,供其余部分中使用。

限制:

  • 不支持递归查询
  • 当在section中使用子查询时,它的结果应该是只有一行的标量。
  • Expression的结果在子查询中不可用。

例子:

示例1:使用常量表达式作为variable

WITH '2019-08-01 15:23:00' as ts_upper_bound
SELECT *
FROM hits
WHERE
EventDate = toDate(ts_upper_bound) AND
EventTime <= ts_upper_bound

示例2:从SELECT子句列表中得到sum(bytes)表达式结果

WITH sum(bytes) as s
SELECT
formatReadableSize(s),
table
FROM system.parts
GROUP BY table // 看这里 group by
ORDER BY s

示例3:使用标量子查询的结果

WITH
(
SELECT sum(bytes)
FROM system.parts
WHERE active
) AS total_disk_usage
SELECT
(sum(bytes) / total_disk_usage) * 100 AS table_disk_usage,
table
FROM system.parts
GROUP BY table
ORDER BY table_disk_usage DESC
LIMIT 10

示例4:在子查询中重用表达式

WITH ['hello'] AS hello
SELECT
hello,
*
FROM
(
WITH ['hello'] AS hello
SELECT hello
)
┌─hello─────┬─hello─────┐
│ ['hello']['hello'] │
└───────────┴───────────┘

WHERE子句

如果基础表引擎支持,where表达式会使用索引和分区进行剪枝。

如果需要测试一个NULL值,请使用IS NULL and IS NOT NULL运算符或者isNullisNotNull函数。否则带有NULL的表达式永远无法通过。

UNION ALL子句

SELECT CounterID, 1 AS table, toInt64(count()) AS c
FROM test.hits
GROUP BY CounterID
UNION ALL
SELECT CounterID, 2 AS table, sum(Sign) AS c
FROM test.visits
GROUP BY CounterID
HAVING c > 0

结果列通过它们的索引进行匹配(在内部的顺序 SELECT). 如果列名称不匹配,则从第一个查询中获取最终结果的名称。

对union执行类型转换。如果有nullable的类型,最终会转化到nullable

属于以下部分的查询 UNION ALL 不能用圆括号括起来。 ORDER BY 和 LIMIT 应用于单独的查询,而不是最终结果。

不支持union distinct。如果你需要 UNION DISTINCT,你可以写 SELECT DISTINCT 子查询中包含 UNION ALL

PREWHERE子句

PREWHERE是更有效地进行过滤的优化。

默认情况下,不指定也会使用。只有在你知道比默认更好的情况下,才去使用。

使用PREWHERE优化,首先只读取执行PREWHERE表达式所需的行。然后读取行其余查询查询所需要的列,但只读取prewhere表达式所在的那些块“true”。使得更少的查询。

该子句具有与 WHERE 相同的含义,区别在于从表中读取数据。 当手动控制 PREWHERE 对于查询中的少数列使用的过滤条件,但这些过滤条件提供了强大的数据过滤。 这减少了要读取的数据量。

查询可以同时指定 PREWHEREWHERE. 在这种情况下, PREWHERE 先于 WHERE.

如果 optimize_move_to_prewhere 设置为0,启发式自动移动部分表达式 WHEREPREWHERE 被禁用。

PREWHERE只有MergeTree族系列引擎的表能够使用。

ORDER BY

对于特殊值的排序

有两种方法 NaNNULL 排序顺序:

  • 默认情况下或与 NULLS LAST 修饰符:首先是值,然后 NaN,然后 NULL.
  • NULLS FIRST 修饰符:第一 NULL,然后 NaN,然后其他值。
SELECT * FROM t_null_nan ORDER BY y NULLS FIRST

LIMIT

LIMIT n, m 允许选择个 m 从跳过第一个结果后的行 n 行。 与 LIMIT m OFFSET n 语法是等效的。

FORMAT

使用命令行客户端时,数据始终以内部高效格式通过网络传递 (Native). 客户端独立解释 FORMAT 查询子句并格式化数据本身(以减轻网络和服务器的额外负担)。

HAVING子句

允许过滤由 GROUP BY 生成的聚合结果. 它类似于 WHERE ,但不同的是 WHERE 在聚合之前执行,而 HAVING 之后进行。

可以从 SELECT 生成的聚合结果中通过他们的别名来执行 HAVING 子句。 或者 HAVING 子句可以筛选查询结果中未返回的其他聚合的结果。

限制:

HAVING如果不执行聚合则无法使用。

INTO OUTFILE子句

INTO OUTFILE filename子句,将其输出重定向到客户端上的指定文件。

OFFSET FETCH Clause

OFFSET offset_row_count {ROW | ROWS}] [FETCH {FIRST | NEXT} fetch_row_count {ROW | ROWS} {ONLY | WITH TIES}]

其实也就是从第几行开始读取几行。

fetch_row_count默认为1。ONLY 选项用于返回紧跟在 OFFSET 省略的行之后的行。

SELECT * FROM test_fetch ORDER BY a OFFSET 1 ROW FETCH FIRST 3 ROWS ONLY;
SELECT * FROM test_fetch ORDER BY a LIMIT 3 OFFSET 1; //等价

The WITH TIES option is used to return any additional rows that tie for the last place in the result set according to the ORDER BY clause. For example, if fetch_row_count is set to 5 but two additional rows match the values of the ORDER BY columns in the fifth row, the result set will contain seven rows.

也就是说与最后一个值一致的也会被包含进行。

CREATE

CREATE DATABASE

创建数据库:

CREATE DATABASE [IF NOT EXISTS] db_name [ON CLUSTER cluster] [ENGINE = engine(...)]
  • on cluster:在指定集群的所有服务器上创建db_name数据库。

CREATE TABLE

请使用ON CLUSTER在集群创建。否则仅仅在本服务器创建。

语法格式:

CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
name1 [type1] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr1] [compression_codec] [TTL expr1],
name2 [type2] [NULL|NOT NULL] [DEFAULT|MATERIALIZED|EPHEMERAL|ALIAS expr2] [compression_codec] [TTL expr2],
...
CONSTRAINT constraint_name_1 CHECK boolean_expr_1,
...
PRIMARY KEY(expr1[, expr2,...])]
)
ENGINE = engine
//PRIMARY KEY(expr1[, expr2,...])] 也可以
COMMENT 'Comment'

创建一个与其他表一样结构的表:

CREATE TABLE [IF NOT EXISTS] [db.]table_name AS [db2.]name2 [ENGINE = engine]

根据一个table_function创建:

CREATE TABLE [IF NOT EXISTS] [db.]table_name AS table_function()

根据一个select创建:会用select的值填充,字段的描述可写可不写

CREATE TABLE [IF NOT EXISTS] [db.]table_name[(name1 [type1], name2 [type2], ...)] ENGINE = engine AS SELECT ...

默认是not null的。可以查看data_type_default_nullable进行设置。

DEFAULT默认值。默认表达式给出,那么该字段类型可省略。

MATHERIALIZED:不能够在INSERT中被指定,因为它总是被计算出来。SELECT *也不会返回这个值。(便于到另一个表INSERT)

EPHEMERAL:这样的列不存储在表中,不能被选择,但可以在 CREATE 语句的默认值中引用。

Alias:It can be used in SELECTs if the alias is expanded during query parsing.

约束会在INSERT的时候被检查。

Defines storage time for values. Can be specified only for MergeTree-family tables.

列压缩编码:默认是使用lz4压缩方式。可以为每个单独的列指定压缩编码。

CREATE TABLE codec_example
(
dt Date CODEC(ZSTD),
ts DateTime CODEC(LZ4HC),
float_value Float32 CODEC(NONE),
double_value Float64 CODEC(LZ4HC(9)),
value Float32 CODEC(Delta, ZSTD)
)
ENGINE = <Engine>
...

支持压缩的表引擎:

  • MergeTree族
  • Log族:lz4
  • Set:默认
  • Join:默认

通用支持的压缩编码:

  • NONE
  • LZ4
  • LZ4HC[(level)]:LZ4 HC (high compression) algorithm with configurable level. Default level: 9. Setting level <= 0 applies the default level. Possible levels: [1, 12]. Recommended level range: [4, 9].
  • ZSTD[(level)]
  • DEFLATE_QPL

特定支持的压缩编码:

加密编码:

  • AES_128_GCM_SIV
  • AES-256-GCM-SIV

临时表:

CREATE TEMPORARY TABLE [IF NOT EXISTS] table_name
(
name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
...
)

RELACE允许原子性地更新表:

{CREATE [OR REPLACE] | REPLACE} TABLE [db.]table_name

CREATE FUNCTION

CREATE FUNCTION name AS (parameter0, ...) -> expression
CREATE FUNCTION linear_equation AS (x, k, b) -> k*x + b;
SELECT number, linear_equation(number, 2, 1) FROM numbers(3);

CREATE DICTIONARY

字典是为了避免ClickHouse里面低效率的维表JOIN而使用的替代方案,它其实也是类似于做了一次维度的nest_loop join,但是它提前被加载到内存,而且复用性更好。

CREATE [OR REPLACE] DICTIONARY [IF NOT EXISTS] [db.]dictionary_name [ON CLUSTER cluster]
(
key1 type1
[DEFAULT|EXPRESSION expr1] [IS_OBJECT_ID],
key2 type2
[DEFAULT|EXPRESSION expr2],
attr1 type2 [DEFAULT|EXPRESSION expr3] [HIERARCHICAL|INJECTIVE],
attr2 type2 [DEFAULT|EXPRESSION expr4] [HIERARCHICAL|INJECTIVE]
)
PRIMARY KEY key1, key2
SOURCE(SOURCE_NAME([param1 value1 ... paramN valueN]))
LAYOUT(LAYOUT_NAME([param_name param_value]))
LIFETIME({MIN min_val MAX max_val | max_val})
SETTINGS(setting_name = setting_value, setting_name = setting_value, ...)
COMMENT 'Comment'
  • LAYOUT:字典在内存中的布局,常用的有(FLAT|HASHED|COMPLEX_KEY_HASHED),其中COMPLEX_KEY_HASHED是多列键值必须要使用的布局;

  • dictGetTOrDefault:获取特定类型的字典属性值,如果找不到则用默认值dictGetTOrDefault('dict_name', 'attr_name', id, default)

  • dictGetHierarchy:查找分层的所有父节点,返回一个Array

  • dictHas:判断是否有某个值,如果没有返回0 dictHas('dict_name', id)

INSET INTO

INSERT INTO [db.]table [(c1, c2, c3)] VALUES (v11, v12, v13), (v21, v22, v23), ...
INSERT INTO insert_select_testtable (* EXCEPT(b)) Values (2, 2);
INSERT INTO [db.]table [(c1, c2, c3)] FROM INFILE file_name [COMPRESSION type] FORMAT format_name

写入与SELECT的列的对应关系是使用位置来进行对应的,尽管它们在SELECT表达式与INSERT中的名称可能是不同的。如果需要,会对它们执行对应的类型转换。

除了VALUES格式之外,其他格式中的数据都不允许出现诸如now()1 + 2等表达式。VALUES格式允许您有限度的使用这些表达式,但是不建议您这么做,因为执行这些表达式总是低效的。

系统不支持的其他用于修改数据的查询:UPDATE, DELETE, REPLACE, MERGE, UPSERT, INSERT UPDATE。 但是,您可以使用 ALTER TABLE ... DROP PARTITION查询来删除一些旧的数据。

如果 SELECT 查询中包含了 input() 函数,那么 FORMAT 必须出现在查询语句的最后。

如果某一列限制了值不能是NULL,那么插入NULL的时候就会插入这个列类型的默认数据,可以通过设置 insert_null_as_default 插入NULL。

性能注意事项:

在进行INSERT时将会对写入的数据进行一些处理,按照主键排序,按照月份对数据进行分区等。所以如果在您的写入数据中包含多个月份的混合数据时,将会显著的降低INSERT的性能。为了避免这种情况:

  • 数据总是以尽量大的batch进行写入,如每次写入100,000行。
  • 数据在写入ClickHouse前预先的对数据进行分组。

在以下的情况下,性能不会下降:

  • 数据总是被实时的写入。
  • 写入的数据已经按照时间排序。

也可以异步的、小规模的插入数据,这些数据会被合并成多个批次,然后安全地写入到表中,通过设置async_insert,可以使用异步插入的方式,请注意,异步插入的方式只支持HTTP协议,并且不支持数据去重。

TRUNCATE语句

TRUNCATE TABLE [IF EXISTS] [db.]name [ON CLUSTER cluster]

TRUNCATE 查询不支持View,File, URL, Buffer 和 Null表引擎。

可以使用 replication_alter_partitions_sync 设置在复制集上等待执行的操作。

通过 replication_wait_for_inactive_replica_timeout 设置,可以指定不活动副本执行 TRUNCATE查询需要等待多长时间(以秒为单位)。

ALTER

ALTER 仅支持 *MergeTreeMerge以及Distributed等引擎表。 该操作有多种形式。

ALTER TABLE [db].name [ON CLUSTER cluster] ADD|DROP|CLEAR|COMMENT|MODIFY COLUMN ...

在语句中,配置一个或多个用逗号分隔的动作。每个动作是对某个列实施的操作行为。

增加列

ADD COLUMN [IF NOT EXISTS] name [type] [default_expr] [codec] [AFTER name_after]

指定列位置:AFTER name_after

删除列

DROP COLUMN [IF EXISTS] name

清空列

CLEAR COLUMN [IF EXISTS] name IN PARTITION partition_name

重置指定分区的值。

增加注释

ALTER TABLE visits COMMENT COLUMN browser 'The table shows the browser used for accessing the site.'

修改列

MODIFY COLUMN [IF EXISTS] name [type] [default_expr] [TTL]

改变列的类型是唯一的复杂型动作 - 它改变了数据文件的内容。对于大型表,执行起来要花费较长的时间。 该操作分为如下处理步骤:

  • 为修改的数据准备新的临时文件
  • 重命名原来的文件
  • 将新的临时文件改名为原来的数据文件名
  • 删除原来的文件

仅仅在第一步是耗费时间的。如果该阶段执行失败,那么数据没有变化。如果执行后续的步骤中失败了,数据可以手动恢复。例外的情形是,当原来的文件从文件系统中被删除了,但是新的数据没有写入到临时文件中并且丢失了。

列操作的 ALTER行为是可以被复制的。这些指令会保存在ZooKeeper中,这样每个副本节点都能执行它们。所有的 ALTER 将按相同的顺序执行。 The query waits for the appropriate actions to be completed on the other replicas. 然而,改变可复制表的列是可以被中断的,并且所有动作都以异步方式执行。

key表达式的修改

MODIFY ORDER BY new_expression

该操作仅支持 MergeTree 系列表 (含 replicated 表)。它会将表的 排序键变成 new_expression (元组表达式)。主键仍保持不变。

该操作是轻量级的,仅会改变元数据。

跳过索引来更改数据

该操作仅支持 MergeTree 系列表 (含 replicated 表)。 下列操作是允许的:

  • ALTER TABLE [db].name ADD INDEX name expression TYPE type GRANULARITY value [FIRST|AFTER name] - 在表的元数据中增加索引说明
  • ALTER TABLE [db].name DROP INDEX name - 从表的元数据中删除索引描述,并从磁盘上删除索引文件

由于只改变表的元数据或者删除文件,因此该操作是轻量级的,也可以被复制到其它节点(通过Zookeeper同步索引元数据)

更改约束

ALTER TABLE [db].name ADD CONSTRAINT constraint_name CHECK expression;
ALTER TABLE [db].name DROP CONSTRAINT constraint_name;

上述语句会从表中增加或删除约束的元数据,因此会被立即处理。 对已有数据的约束检查 将不会执行

对可复制表的操作可通过Zookeeper传播到其它副本节点。

更改分区及文件块

允许进行下列关于 partitions 的操作:

  • DETACH PARTITION — 将分区数据移动到 detached ,并且忘记它
  • DROP PARTITION — 删除一个partition.
  • ATTACH PART|PARTITION — 将detached 目录中的分区重新添加到表中.
  • ATTACH PARTITION FROM — 从表中复制数据分区到另一张表,并添加分区
  • REPLACE PARTITION — 从表中复制数据分区到其它表及副本
  • MOVE PARTITION TO TABLE — 从表中复制数据分区到其它表.
  • CLEAR COLUMN IN PARTITION — 重置分区中某个列的值
  • CLEAR INDEX IN PARTITION — 重置分区中指定的二级索引
  • FREEZE PARTITION — 创建分区的备份
  • FETCH PARTITION — 从其它服务器上下载分
  • MOVE PARTITION|PART — 将分区/数据块移动到另外的磁盘/卷

更改表的TTL

ALTER TABLE table-name MODIFY TTL ttl-expression

ALTER操作的同步性

对于不可复制的表,所有 ALTER操作都是同步执行的。对于可复制的表,ALTER操作会将指令添加到ZooKeeper中,然后会尽快的执行它们。然而,该操作可以等待其它所有副本将指令执行完毕。

对于 ALTER ... ATTACH|DETACH|DROP操作,可以通过设置 replication_alter_partitions_sync 来启用等待。可用参数值: 0 – 不需要等待; 1 – 仅等待自己执行(默认); 2 – 等待所有节点

Mutations

Mutations是一类允许对表的行记录进行删除或更新的ALTER操作。相较于标准的 UPDATEDELETE 用于少量行操作而言,Mutations用来对表的很多行进行重量级的操作。该操作支持 MergeTree系列表,包含支持复制功能的表。

ALTER TABLE [db.]table [ON CLUSTER cluster] DELETE WHERE filter_expr

删除匹配指定过滤表达式的数据。实现为突变.

查询处理的同步性由mutations_sync设置定义。缺省情况下,是异步的。

ALTER TABLE [db.]table UPDATE column1 = expr1 [, ...] WHERE filter_expr

操作与指定过滤表达式相匹配的数据。作为一个变更 mutation来实现.

函数部分

https://clickhouse.com/docs/zh/sql-reference/functions/

用到了查。

最后

以上就是靓丽蓝天为你收集整理的ClickHouse的全部内容,希望文章能够帮你解决ClickHouse所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部