clickhouse表引擎

表引擎

对于大多数正式的任务,应该使用MergeTree族中的引擎。
Clickhouse 中最强大的表引擎当属 MergeTree (合并树)引擎及该系列(*MergeTree)中的其他引擎。

日志引擎系列

这些引擎是为了需要写入许多小数据量(少于一百万行)的表的场景而开发的。

  • StripeLog
  • Log
  • TinyLog

相同点:

  • 数据存储在磁盘上。
  • 写入时将数据追加在文件末尾。
  • 不支持索引。
    这意味着 SELECT 在范围查询时效率不高。
  • 非原子地写入数据。
    如果某些事情破坏了写操作,例如服务器的异常关闭,将会得到一张包含了损坏数据的表。

不同点:

  • Log 引擎为表中的每一列使用不同的文件。并发读取,写入操作则阻塞读取和其它写入。Log 引擎适用于临时数据,write-once 表以及测试或演示目的。
  • StripeLog 将所有的数据存储在一个文件中。
  • TingLog 引擎不支持并行读取和并发数据访问,并将每一列存储在不同的文件中。

StripeLog

#建表
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    column1_name [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    column2_name [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
) ENGINE = StripeLog

StripeLog 引擎将所有列存储在一个文件中。对每一次 Insert 请求,ClickHouse 将数据块追加在表文件的末尾,逐列写入。
ClickHouse 为每张表写入以下文件:

  • data.bin — 数据文件。
  • index.mrk — 带标记的文件。标记包含了已插入的每个数据块中每列的偏移量。

StripeLog 引擎不支持 ALTER UPDATE 和 ALTER DELETE 操作。
带标记的文件使得 ClickHouse 可以并行的读取数据。这意味着 SELECT 请求返回行的顺序是不可预测的。使用 ORDER BY 子句对行进行排序。
ClickHouse 在查询数据时使用多线程。每个线程读取单独的数据块并在完成后独立的返回结果行。这样的结果是,大多数情况下,输出中块的顺序和输入时相应块的顺序是不同的。

TinyLog

最简单的表引擎,用于将数据存储在磁盘上。每列都存储在单独的压缩文件中。写入时,数据将附加到文件末尾。不支持索引。
并发数据访问不受任何限制: 如果同时从表中读取并在不同的查询中写入,则读取操作将抛出异常 。如果同时写入多个查询中的表,则数据将被破坏。
这种表引擎的典型用法是 write-once:首先只写入一次数据,然后根据需要多次读取。查询在单个流中执行。换句话说,此引擎适用于相对较小的表(建议最多1,000,000行)。

特殊引擎

Memory

Memory 引擎以未压缩的形式将数据存储在内存中。数据完全以读取时获得的形式存储。换句话说,从这张表中读取是很轻松的。并发数据访问是同步的。锁范围小:读写操作不会相互阻塞。不支持索引。阅读是并行化的。
在简单查询上达到最大生产率(超过10 GB /秒),因为没有磁盘读取,不需要解压缩或反序列化数据。(值得注意的是,在许多情况下,与 MergeTree 引擎的性能几乎一样高)。重新启动服务器时,表中的数据消失,表将变为空。通常,使用此表引擎是不合理的。

Merge

Merge 引擎本身不存储数据,但可用于同时从任意多个其他的表中读取数据。 读是自动并行的,不支持写入。读取时,那些被真正读取到数据的表的索引(如果有的话)会被使用。
Merge 引擎的参数:一个数据库名和一个用于匹配表名的正则表达式。

Merge(db, 'regex')

Merge 引擎的一个典型应用是可以像使用一张表一样使用大量的 TinyLog 表。

Distributed

分布式引擎本身不存储数据, 但可以在多个服务器上进行分布式查询。 读是自动并行的。读取时,远程服务器表的索引(如果有的话)会被使用。
分布式引擎参数:服务器配置文件中的集群名,远程数据库名,远程表名,数据分片键(可选)。

Distributed(cluster, db, table[, sharding_key])

远程服务器不仅用于读取数据,还会对尽可能数据做部分处理。分片是指包含数据不同部分的服务器(要读取所有数据,必须访问所有分片)。 副本是存储复制数据的服务器(要读取所有数据,访问任一副本上的数据即可)。配置了副本,读取操作会从每个分片里选择一个可用的副本。可配置负载平衡算法(挑选副本的方式)。 如果跟服务器的连接不可用,则在尝试短超时的重连。如果重连失败,则选择下一个副本,依此类推。如果跟所有副本的连接尝试都失败,则尝试用相同的方式再重复几次。 该机制有利于系统可用性,但不保证完全容错:如有远程服务器能够接受连接,但无法正常工作或状况不佳。

合并树引擎系列

MergeTree

MergeTree 引擎系列的基本理念如下:当有巨量数据要插入到表中时,需要高效地一批批写入数据片段,并希望这些数据片段在后台按照一定规则合并。
应对表的并发访问,我们使用多版本机制。换言之,当同时读和更新表时,数据从当前查询到的一组片段中读取。没有冗长的的锁。插入不会阻碍读取。对表的读操作是自动并行的。

特点
  • 存储的数据按主键排序。
  • 允许使用分区(在指定了主键的情况下)。查询中指定了分区键时 ClickHouse 会自动截取分区数据。这也有效增加了查询性能。
  • 支持数据副本。
  • 支持数据采样。
#建表
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(
    name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],
    name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],
    ...
    INDEX index_name1 expr1 TYPE type1(...) GRANULARITY value1,
    INDEX index_name2 expr2 TYPE type2(...) GRANULARITY value2
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
存储

表由按主键排序的数据片段组成。
当数据被插入到表中时,会分成数据片段并按主键的字典序排序。
不同分区的数据会被分成不同的片段,ClickHouse 在后台合并数据片段以便更高效存储。不会合并来自不同分区的数据片段。这个合并机制并不保证相同主键的所有行都会合并到同一个数据片段中。

主键与排序键
  • 稀疏索引让你能操作有巨量行的表。因为这些索引是常驻内存(RAM)的。
  • ClickHouse 不要求主键惟一。所以,你可以插入多条具有相同主键的行。
  • 主键中列的数量并没有明确的限制。
  • 长的主键会对插入性能和内存消耗有负面影响。
  • 默认情况下主键跟排序键相同。指定一个跟排序键(用于排序数据片段中行的表达式) 不一样的主键(用于计算写到索引文件的每个标记值的表达式)是可以的。 这种情况下,主键表达式元组必须是排序键表达式元组的一个前缀。

ReplacingMergeTree

ENGINE = ReplacingMergeTree([ver])

该引擎和MergeTree的不同之处在于它会删除具有相同主键的重复项。
数据的去重只会在合并的过程中出现。合并会在未知的时间在后台进行,因此你无法预先作出计划。有一些数据可能仍未被处理。尽管你可以调用 OPTIMIZE 语句发起计划外的合并,但请不要指望使用它,因为 OPTIMIZE 语句会引发对大量数据的读和写。
因此,ReplacingMergeTree 适用于在后台清除重复的数据以节省空间,但是它不保证没有重复的数据出现。
并的时候,ReplacingMergeTree 从所有具有相同主键的行中选择一行留下: 如果 ver 列未指定,选择最后一条。 如果 ver 列已指定,选择 ver 值最大的版本。

你可能感兴趣的:(clickhouse表引擎)