ClickHouse表引擎
1 概述
表引擎在ClickHouse中的作用十分关键,表引擎有如下作用:
(1)数据如何存储,存在哪,数据写到哪, 怎样读取数据;
(2)支持哪些查询以及如何支持;
(3)并发数据访问;
(4)索引的使用;
(5)是否可以执行多线程的请求;
(6)数据如何同步。
2 表引擎系列
2.1 MergeTree系列
MergeTree系列是对于高负载任务的最通用和最实用的表引擎。这些引擎共享的属性是快速数据插入和后续的后台数据处理。想要高效地一批批写入数据片段,并希望这些数据片段在后台按照一定规则合并。相比在插入时不断修改(重写)数据进存储,这种策略会高效很多。MergeTree系列引擎支持数据复制、分区和其他引擎不支持的特性。有如下特点:①数据按照主键进行排序;②可以使用分区(如果指定了主键);③支持数据副本;④支持数据采样
2.1.1 MergeTree
MergeTree 引擎支持索引,通过主键和日期来构建索引, 同时提供 数据的实时更新能力. 这是目前 ClickHouse处理能力最好的引擎。
注意:①不能和Merge 引擎相混淆。
②MergeTree虽然有主键索引,但是其主要作用是加速查询,而不是类似MySQL等数据库用来保持记录唯一。即便在Compaction完成后,主键相同的数据行也仍旧共同存在。
建表语句如下
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()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[TTL expr [DELETE|TO DISK 'xxx'|TO VOLUME 'xxx'], ...]
[SETTINGS name=value, ...]
参数说明:
参数 | 说明 |
---|---|
ENGINE = MergeTree() | ENGINE:引擎名和参数 |
PARTITION BY expr | PARTITION BY:分区键,按月分区采用“YYYYMM”格式,可以使用toYYYYMM (date_column)表达式,date_column类型必须是Date |
ORDER BY expr | ORDER BY:排序键,列的元组或任意表达式 (字段的组合), 或者单独的表达式。如:ORDER BY (CounterID, EventDate) |
PRIMARY KEY expr | PRIMARY KEY:主键,需要与排序键字段不同,默认主键与排序键相同 |
SAMPLE BY expr | SAMPLE BY:抽样表达式,要用抽样表达式,主键必须包含这个表达式 |
TTL expr [DELETE |TO DISK ‘xxx’ TO VOLUME ‘xxx’], … | TTL:指定行存储时间和定义磁盘与卷之间自动部件移动逻辑的规则列表。如:TTL create_time + INTERVAL 1 MONTH(表数据的生命周期为期一个月 )它的含义是当ClickHouse合并数据分区时, 会根据create_time这一列的时间数据以及之后一个月的这样一周期内的数据进行保存,不在这一时间段内的数据,ck就是主动删除分区目录下的列文件 |
SETTINGS name=value, … |
SETTINGS:影响MergeTree性能的额外参数 ①index_granularity:索引粒度,索引键相邻标记间的数据行数,默认8192 ②use_minimalistic_part_header_in_zookeeper:在Zookeeper中的存储方式 ③min_merge_bytes_to_use_direct_io:使用直接I/O来操作磁盘的合并操作时的最小数据量 |
测试:test_mt表的主键为(id, create_time),并且按照主键进行存储排序,按照create_time进行数据分区,根据create_time这一列的时间数据保留最近一个月。
CREATE TABLE test_mt ( \id UInt16, \create_time Date, \comment Nullable(String) \
) ENGINE = MergeTree() \
PARTITION BY create_time \
ORDER BY (id, create_time) \
PRIMARY KEY (id, create_time) \
TTL create_time + INTERVAL 1 MONTH \
SETTINGS index_granularity=8192;
插入数据
insert into test_mt values(0, '2020-01-01', null);
insert into test_mt values(0, '2020-01-01', null);
insert into test_mt values(1, '2020-01-02', null);
insert into test_mt values(2, '2020-01-03', null);
查询数据
SELECT count(*)
FROM test_mt
┌─count()─┐
│ 4 │
└─────────┘SELECT *
FROM test_mt ┌─id─┬─create_time─┬─comment─┐
│ 2 │ 2020-01-03 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 1 │ 2020-01-02 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 0 │ 2020-01-01 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 0 │ 2020-01-01 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
可以发现虽然主键id、create_time相同的数据只有3条数据,但是结果却有4行。因为MergeTree采用类似LSM tree的结构,很多存储层处理逻辑直到Compaction期间才会发生。因此强制后台compaction执行
optimize table test_mt final;
再次查询,发现没有数据了。
SELECT count(*)
FROM test_mt ┌─count()─┐
│ 0 │
└─────────┘
是因为TTL的原因,我们在表上加了TTL当表内的数据过期时, ClickHouse会删除所有对应的行。如果是列上加TTL,当列字段中的值过期时, ClickHouse会将它们替换成数据类型的默认值。如果分区内,某一列的所有值均已过期,则ClickHouse会从文件系统中删除这个分区目录下的列文件。
如果没有加TTL的查询出来应该是如下所示
SELECT count(*)
FROM test_mt ┌─count()─┐
│ 4 │
└─────────┘select * from test_mt;
┌─id─┬─create_time─┬─comment─┐
│ 2 │ 2020-01-03 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 1 │ 2020-01-02 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 0 │ 2020-01-01 │ ᴺᵁᴸᴸ │
│ 0 │ 2020-01-01 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
2.1.2 ReplacingMergeTree
ReplacingMergeTree在MergeTree的基础上,添加了处理重复数据的功能,也就是会删除具有相同主键的重复项,这就是与MergeTree的不同之处。
注意:数据的去重是在合并的过程中出现的,合并会在未知的时间在后台运行,所以无法预先做出计划。所以可能有一些数据任未被处理,因此ReplacingMergeTree适用于在后台清理重复数据以节省空间,但是不能保证没有重复的数据出现。
语法:
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...
) ENGINE = ReplacingMergeTree([ver])
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
参数说明:ENGINE = ReplacingMergeTree([ver]),这个ver是版本列,类型是UInt*,Date或者DateTime,合并的时候ReplacingMergeTree从具有相同主键的行中选择一行留下,如果ver列没有指定,选择最后一条,如果ver列已指定,选择ver最大的版本。其他的参考MergeTree的
测试:
CREATE TABLE test_rmt (\id UInt16,\create_time Date,\comment Nullable(String)\
) ENGINE = ReplacingMergeTree()\PARTITION BY create_time\ORDER BY (id, create_time)\PRIMARY KEY (id, create_time)\TTL create_time + INTERVAL 1 MONTH\SETTINGS index_granularity=8192;
插入数据:
insert into test_rmt values(0, '2020-05-01', null);
insert into test_rmt values(0, '2020-05-01', null);
insert into test_rmt values(1, '2020-05-02', null);
insert into test_rmt values(2, '2020-05-03', null);
查询结果:
SELECT count(*)
FROM test_rmt ┌─count()─┐
│ 4 │
└─────────┘SELECT *
FROM test_rmt ┌─id─┬─create_time─┬─comment─┐
│ 1 │ 2020-05-02 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 2 │ 2020-05-03 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 0 │ 2020-05-01 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 0 │ 2020-05-01 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
可以发现数据还是4条,强制后台compaction
optimize table test_rmt final;
再次查询
SELECT count(*)
FROM test_rmt ┌─count()─┐
│ 3 │
└─────────┘SELECT *
FROM test_rmt ┌─id─┬─create_time─┬─comment─┐
│ 1 │ 2020-05-02 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 2 │ 2020-05-03 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
┌─id─┬─create_time─┬─comment─┐
│ 0 │ 2020-05-01 │ ᴺᵁᴸᴸ │
└────┴─────────────┴─────────┘
总结:虽然ReplacingMergeTree提供了主键去重的能力,但是仍旧有以下缺点:①在没有彻底optimize之前,可能无法达到主键去重的效果,部分数据已经去重,部分没有去重②在分布式情况下,相同primary key的数据可能被sharding到不同节点上,不同shard间可能无法去重③无法预测optimize具体执行时间点④海量数据下要手动执行optimize需要消耗大量时间,无法满足业务即时查询的需求
2.1.3 SummingMergeTree
SummingMergeTree与MergeTree不区别在与当合并SummingMergeTree表的数据片段时,会把相同主键的行合并为一行,这一行包含了被合并的行中具有数值数据类型的列的汇总值,对于不可加的列会取出一个最先出现的值。如果相同的主键对应大量的行,可以显著减少存储空间并加快数据查询的速度。
语法:
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...
) ENGINE = SummingMergeTree([columns])
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[SETTINGS name=value, ...]
参数说明:ENGINE = SummingMergeTree([columns]):[columns]表示将要被汇总的列的列名的元组。
测试:
CREATE TABLE test_smt(\date Date,\name String,\money UInt16,\not_sum UInt16\
)\
ENGINE = SummingMergeTree(money)\
PARTITION by date \
ORDER by (date,name);
插入数据:
insert into test_smt values ('2020-05-01', 'zs', 6, 1);
insert into test_smt values ('2020-05-01', 'ls', 8, 2);
insert into test_smt values ('2020-05-02', 'ww', 6, 3);
insert into test_smt values ('2020-05-02', 'ww', 8, 4);
insert into test_smt values ('2020-05-03', 'zl', 6, 5);
查询:
SELECT *
FROM test_smt ┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-02 │ ww │ 8 │ 4 │
└────────────┴──────┴───────┴─────────┘
┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-01 │ zs │ 6 │ 1 │
└────────────┴──────┴───────┴─────────┘
┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-03 │ zl │ 6 │ 5 │
└────────────┴──────┴───────┴─────────┘
┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-01 │ ls │ 8 │ 2 │
└────────────┴──────┴───────┴─────────┘
┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-02 │ ww │ 6 │ 3 │
└────────────┴──────┴───────┴─────────┘
通过GROUP BY进行聚合查询
SELECT date, name, sum(money), min(not_sum)
FROM test_smt
GROUP BY date, name┌───────date─┬─name─┬─sum(money)─┬─min(not_sum)─┐
│ 2020-05-01 │ ls │ 8 │ 2 │
│ 2020-05-02 │ ww │ 14 │ 3 │
│ 2020-05-03 │ zl │ 6 │ 5 │
│ 2020-05-01 │ zs │ 6 │ 1 │
└────────────┴──────┴────────────┴──────────────┘
强制compaction
optimize table test_smt final;
再次查询
SELECT *
FROM test_smt ┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-03 │ zl │ 6 │ 5 │
└────────────┴──────┴───────┴─────────┘
┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-01 │ ls │ 8 │ 2 │
│ 2020-05-01 │ zs │ 6 │ 1 │
└────────────┴──────┴───────┴─────────┘
┌───────date─┬─name─┬─money─┬─not_sum─┐
│ 2020-05-02 │ ww │ 14 │ 3 │
└────────────┴──────┴───────┴─────────┘
2.1.4 ClollapsingMergeTree
ClollapsingMergeTree实现了对ReplacingMergeTree功能的限制,在建表语句中指定一个标记列sign,后台Compaction时会将主键相同,sign相反的行进行删除。ClollapsingMergeTree将行安装sign的值分为两类:sign=1为状态行,sign=-1位取消行。每次需要新增状态时,写入一行状态行,需要删除状态时,写入一行取消行。后台在Compaction时,状态行与取消行会自动做折叠(删除),而尚未进行Compaction的数据,状态行与取消行同时存在。
为了能够达到主键折叠(删除)的目的,对业务层进行适当改造:①执行删除操作需要写入取消行,而取消行中需要包含与原始状态行主键一样的数据(Sign列除外)。所以在应用层需要记录原始状态行的值,或者在执行删除操作前先查询数据库获取原始状态行。②由于后台Compaction时机无法预测,在发起查询时,状态行和取消行可能尚未被折叠;另外,ClickHouse无法保证primary key相同的行落在同一个节点上,不在同一节点上的数据无法折叠。因此在进行count(*)、sum(col)等聚合计算时,可能会存在数据冗余的情况。为了获得正确结果,业务层需要改写SQL,将count()、sum(col)分别改写为sum(Sign)、sum(col * Sign)。
测试:
CREATE TABLE test_cmt1(\UserID UInt64,\PageViews UInt8,\Duration UInt8,\Sign Int8\
)\
ENGINE = CollapsingMergeTree(Sign)\
ORDER BY UserID;
插入状态行,sign列的值为1
INSERT INTO test_cmt1 VALUES (123456, 6, 88, 1);
插入一行取消行,用于抵消上述状态行。sign列的值为-1,其余值与状态行一致;并且插入一行主键相同的新状态行,用来将PageViews从6更新至7,将Duration从888更新为889.
INSERT INTO test_cmt1 VALUES (123456, 6, 88, -1), (123456, 7, 90, 1);
查询数据:可以看到未Compaction之前,状态行与取消行共存。
SELECT *
FROM test_cmt1 ┌─UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 123456 │ 6 │ 88 │ 1 │
└────────┴───────────┴──────────┴──────┘
┌─UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 123456 │ 6 │ 88 │ -1 │
│ 123456 │ 7 │ 90 │ 1 │
└────────┴───────────┴──────────┴──────┘
为了获取正确的sum值,需要改写SQL: sum(PageViews) => sum(PageViews * Sign)、 sum(Duration) => sum(Duration * Sign)
SELECT UserID, sum(PageViews * Sign) AS PageViews, sum(Duration * Sign) AS Duration
FROM test_cmt1
GROUP BY UserID
HAVING sum(Sign) > 0┌─UserID─┬─PageViews─┬─Duration─┐
│ 123456 │ 7 │ 90 │
└────────┴───────────┴──────────┘
强制后台Compaction
optimize table test_cmt1 final;
再次查询,可以看到状态行、取消行已经被折叠,只剩下最新的一行状态行。
SELECT *
FROM test_cmt1 ┌─UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 123456 │ 7 │ 90 │ 1 │
└────────┴───────────┴──────────┴──────┘
CollapsingMergeTree虽然解决了主键相同的数据即时删除的问题,但是状态持续变化且多线程并行写入情况下,状态行与取消行位置可能乱序,导致无法正常折叠。
CREATE TABLE test_cmt2(\UserID UInt64,\PageViews UInt8,\Duration UInt8,\Sign Int8\
)\
ENGINE = CollapsingMergeTree(Sign)\
ORDER BY UserID;
先插入取消行,然后后插入状态行
INSERT INTO test_cmt2 VALUES (123456, 6, 88, -1);
INSERT INTO test_cmt2 VALUES (123456, 6, 88, 1);
强制Compaction
optimize table test_cmt2 final;
查询
select * from test_cmt2;
可以看到即便Compaction之后也无法进行主键折叠: 2行数据仍旧都存在。
SELECT *
FROM test_cmt2 ┌─UserID─┬─PageViews─┬─Duration─┬─Sign─┐
│ 123456 │ 6 │ 88 │ -1 │
│ 123456 │ 6 │ 88 │ 1 │
└────────┴───────────┴──────────┴──────┘
为了解决CollapsingMergeTree乱序写入情况下无法正常折叠问题,VersionedCollapsingMergeTree表引擎在建表语句中新增了一列Version,用于在乱序情况下记录状态行与取消行的对应关系。主键相同,且Version相同、Sign相反的行,在Compaction时会被删除。
与CollapsingMergeTree类似, 为了获得正确结果,业务层需要改写SQL,将count()、sum(col)分别改写为sum(Sign)、sum(col * Sign)。
2.1.5 AggregatingMergeTree
AggregatingMergeTree与MergeTree的区别在于会进行预先的聚合,用于提升聚合计算的性能。与SummingMergeTree的区别在于SummingMergeTree对于非主键列进行sum聚合,而AggregatingMergeTree则可以指定各种聚合函数。
AggregatingMergeTree需要结合物化视图或者ClickHouse的特殊数据类型ArrregateFunction一起使用,在insert写入的时候需要使用-State语法,在select查询的时候使用-Merge语法。
语法:
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster]
(name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1],name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2],...
) ENGINE = AggregatingMergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[SAMPLE BY expr]
[TTL expr]
[SETTINGS name=value, ...]
(1)结合物化视图
CREATE TABLE test_amt1(\UserID UInt64,\CounterID UInt8,\StartDate Date,\Sign Int8\
)\
ENGINE = CollapsingMergeTree(Sign)\
ORDER BY UserID;
对test_amt建立物化视图,进行预先聚合。预先聚合使用的函数分别为: sumState, uniqState。对应于写入语法-State.
CREATE MATERIALIZED VIEW test_amt1_view\
ENGINE = AggregatingMergeTree() PARTITION BY toYYYYMM(StartDate) ORDER BY (CounterID, StartDate)\
AS SELECT\CounterID,\StartDate,\sumState(Sign) AS Visits,\uniqState(UserID) AS Users\
FROM test_amt1\
GROUP BY CounterID, StartDate;
插入数据
INSERT INTO test_amt1 VALUES(123, 0, '2020-05-01', 3);
INSERT INTO test_amt1 VALUES(123, 1, '2020-05-01', 3);
INSERT INTO test_amt1 VALUES(111, 2, '2020-05-02', 2);
对物化视图进行最终的聚合操作。使用的聚合函数为 sumMerge, uniqMerge。
SELECT \StartDate, \sumMerge(Visits) AS Visits, \uniqMerge(Users) AS Users\
FROM test_amt1_view \
GROUP BY StartDate\
ORDER BY StartDate ASC┌──StartDate─┬─Visits─┬─Users─┐
│ 2020-05-01 │ 6 │ 1 │
│ 2020-05-02 │ 2 │ 1 │
└────────────┴────────┴───────┘
普通函数 sum, uniq不再可以使用,会报错: Illegal type AggregateFunction(sum, Int8) of argument
(2)配合特殊数据类型AggregateFunction使用
CREATE TABLE test_amt2(\CounterID UInt8,\StartDate Date,\Money UInt64,\UserID UInt64\
) ENGINE = MergeTree() \
PARTITION BY toYYYYMM(StartDate) \
ORDER BY (CounterID, StartDate);
插入数据
INSERT INTO test_amt2 VALUES(111, '2020-05-01', 10, 1);
INSERT INTO test_amt2 VALUES(111, '2020-05-01', 12, 5);
INSERT INTO test_amt2 VALUES(122, '2020-05-02', 9, 2);
建立预先聚合表,其中UserID一列的类型为:AggregateFunction(uniq, UInt64)
CREATE TABLE test_amt2_agg(\CounterID UInt8,\StartDate Date,\Money AggregateFunction(sum, UInt64),\UserID AggregateFunction(uniq, UInt64)\
) ENGINE = AggregatingMergeTree() \
PARTITION BY toYYYYMM(StartDate) \
ORDER BY (CounterID, StartDate);
从明细表中读取数据,插入聚合表,子查询中使用的聚合函数为 uniqState
INSERT INTO test_amt2_agg SELECT \CounterID, \StartDate, \sumState(Money),\uniqState(UserID)\
FROM test_amt2 \
GROUP BY \CounterID, \StartDate
注意:不能使用普通insert语句向AggregatingMergeTree中插入数据。会报错:Cannot convert UInt64 to AggregateFunction(uniq, UInt64)
从聚合表中查询,select中使用的聚合函数为uniqMerge
SELECT CounterID,StartDate,sumMerge(Money),uniqMerge(UserID) AS state\
FROM test_amt2_agg \
GROUP BY \CounterID, \StartDateSELECT CounterID, StartDate, sumMerge(Money), uniqMerge(UserID) AS state
FROM test_amt2_agg
GROUP BY CounterID, StartDate┌─CounterID─┬──StartDate─┬─sumMerge(Money)─┬─state─┐
│ 122 │ 2020-05-02 │ 9 │ 1 │
│ 111 │ 2020-05-01 │ 22 │ 2 │
└───────────┴────────────┴─────────────────┴───────┘
2.2 Log系列
Log系列表引擎功能相对简单,轻量级引擎主要用于快速写入小表(1百万行左右的表),然后全部读出的场景。
特点:
(1)数据被顺序append写到磁盘上。
(2)不支持delete、update。
(3)不支持index。
(4)不支持原子性写。
(5)insert会阻塞select操作。
TinyLog,StripLog,Log区别如下:①TinyLog:不支持并发读取数据文件,查询性能较差;格式简单,适合用来暂存中间数据。②StripLog:支持并发读取数据文件,查询性能比TinyLog好;将所有列存储在同一个大文件中,减少了文件个数。③Log:支持并发读取数据文件,查询性能比TinyLog好;每个列会单独存储在一个独立文件中。
2.2.1 TinyLog
最简单的表引擎,用于将数据存储在磁盘上。每列都存储在单独的压缩文件中,写入时,数据将附加到文件末尾。该引擎没有并发控制,如果同时从表中读取和写入数据,则读取操作将抛出异常;如果同时写入多个查询中的表,则数据将被破坏。
不支持索引。
测试:
CREATE TABLE test_tl (\id UInt16,\name String)\
ENGINE=TinyLog;
插入数据:
INSERT INTO test_tl (id, name) values (1, 'zs');
进入ClickHouse的test_tl表的数据存储目录
[root@ambari01 test_tl]# cd /data/clickhouse/data/test/test_tl[root@ambari01 test_tl]# ll
total 12
-rw-r----- 1 clickhouse hadoop 28 May 22 18:07 id.bin
-rw-r----- 1 clickhouse hadoop 29 May 22 18:07 name.bin
-rw-r----- 1 clickhouse hadoop 64 May 22 18:07 sizes.json
id.bin和name.bin是压缩过的对应的列的数据,sizes.json 中记录了每个 *.bin 文件的大小。
[root@ambari01 test_tl]# cat sizes.json
{"yandex":{"id%2Ebin":{"size":"28"},"name%2Ebin":{"size":"29"}}}
2.3 Integration系列
该系统表引擎主要用于将外部数据导入到ClickHouse中,或者在ClickHouse中直接操作外部数据源。
2.3.1 Kafka
将Kafka Topic中的数据直接导入到ClickHouse。
2.3.2 MySQL
将Mysql作为存储引擎,直接在ClickHouse中对MySQL表进行select等操作。
2.3.3 JDBC/ODBC
通过指定jdbc、odbc连接串读取数据源。
2.3.4 HDFS
直接读取HDFS上的特定格式的数据文件;
2.4 Special系列
Special系列的表引擎,是为了特定场景而定制的,不做详述。
Memory:将数据存储在内存中,重启后会导致数据丢失。查询性能极好,适合于对于数据持久性没有要求的1亿一下的小表。在ClickHouse中,通常用来做临时表。
Buffer:为目标表设置一个内存buffer,当buffer达到了一定条件之后会flush到磁盘。
File:直接将本地文件作为数据存储。
Null:写入数据被丢弃、读取数据为空。
ClickHouse表引擎相关推荐
- 【clickhouse】ClickHouse表引擎 MergeTree 数据生命周期
1.概述 转载:ClickHouse表引擎 MergeTree 数据生命周期 TTL(Time To Live)表示数据的存活时间,在 Merge 中可以为某个字段或者整个表设置TTL. 如果设置列级 ...
- 【clickhouse】ClickHouse表引擎 MergeTree 索引与数据存储方式 一级索引 二级索引
1.概述 转载:ClickHouse表引擎 MergeTree 索引与数据存储方式 2.一级索引 MergeTree 主键使用 primary key 定义,定义主键后,会将数据依据 index_gr ...
- clickhouse表引擎-合并树系列
目录 1 clickhouse表引擎-合并树系列简介 2 MergeTree引擎 2.1 建表语法 2.2 创建最简单的MergerTree引擎表 2.3 插入数据 2.4 查看目录结构 2.5 指定 ...
- ClickHouse表引擎到底怎么选
引言 表引擎在ClickHouse中的作用十分关键,直接决定了数据如何存储和读取.是否支持并发读写.是否支持index.支持的query种类.是否支持主备复制等. ClickHouse提供了大约28种 ...
- 大数据培训ClickHouse表引擎
表引擎 表引擎(即表的类型)决定了: 1)数据的存储方式和位置,写到哪里以及从哪里读取数据 2)支持哪些查询以及如何支持. 3)并发数据访问. 4)索引的使用(如果存在). 5)是否可以执行多线程请求 ...
- 3、ClickHouse表引擎-MergeTree引擎
ClickHouse系列文章 1.ClickHouse介绍 2.clickhouse安装与简单验证(centos) 3.ClickHouse表引擎-MergeTree引擎 4.clickhouse的L ...
- ClickHouse 表引擎 ClickHouse性能调优
https://clickhouse.com/ 引子 什么是"更快"? 顺序读/写吞吐量? 随机读/写延迟? 特定并行性和工作负载下的IOPS. 显然RAM可能比磁盘慢,例如单个c ...
- ClickHouse表引擎详解
ClickHouse 表引擎 ClickHouse 的表引擎是 ClickHouse 服务的核心,它们决定了 ClickHouse 的以下行为: 1.数据的存储方式和位置. 2.支持哪些查询操作以及如 ...
- ClickHouse表引擎之Integration系列
Integration系统表引擎主要用于将外部数据导入到ClickHouse中,或者在ClickHouse中直接操作外部数据源. 1 Kafka 1.1 Kafka引擎 将Kafka Topi ...
最新文章
- 为什么可以说Java语言是准动态语言?
- Docker镜像的分层和镜像的创建(Dockerfile)
- 了不起的华人女数学家们
- 下列哪个适合做链栈_外贸企业如何做Google推广?自然排名和付费广告哪个更适合你?...
- duilib CTileLayoutUI 控件
- 第四届中国软件工程大会征文通知
- wtforms Form实例化流程(源码解析)
- 2017-2018-1 20179215 《从问题到程序》第三章
- tomcat下载安装步骤(超详细)
- win10无线投屏_win8/win10笔记本无线投影到电视
- 2016 hitb-facebook-ctf capture-mexico-tls RSA-CRT-Attack
- git deamon 一个简单的git服务器
- 视频数据丢失怎么办 怎样找回丢失的视频数据
- html游戏代码20行,js贪吃蛇源代码 20行js代码实现的贪吃蛇大战?
- java候选码计算的替换法_数据库闭包和候选码求解方法
- chrome打开html文件显示不全,谷歌浏览器显示不全怎么办_chrome浏览器打开的网页显示不完整如何解决-win7之家...
- Windows 11 下 Virtualbox 6.1.34 出现 End kernel panic - not syncing: attempted to kill the idle task
- 网络发现自动关闭不能启用、无法启用文件和打印共享的解决办法
- ubuntu 12.04 给四个工作区设置不同壁纸
- Java 面试的“完美圣经”,有了这些还愁面试吗?