|NO.Z.00005|——————————|BigDataEnd|——|Hadoop&OLAP_ClickHouse.V02|——|ClickHouse.v02|表引擎日志|Memory|Merge|

一、表引擎
### --- 表引擎(即表的类型)决定了:
~~~     数据的存储方式和位置,写到哪里以及从哪里读取数据
~~~     支持哪些查询以及如何支持。
~~~     并发数据访问。
~~~     索引的使用(如果存在)。
~~~     是否可以执行多线程请求。
~~~     数据复制参数。

~~~     # ClickHouse的表引擎有很多,下面介绍其中几种,
~~~     # 对其他引擎有兴趣的可以去查阅官方文档
~~~     # https://clickhouse.yandex/docs/zh/operations/table_engines/
二、日志
### --- TinyLog

~~~     最简单的表引擎,用于将数据存储在磁盘上。
~~~     每列都存储在单独的压缩文件中,写入时,数据将附加到文件末尾。该引擎没有并发控制
~~~     如果同时从表中读取和写入数据,则读取操作将抛出异常;
~~~     如果同时写入多个查询中的表,则数据将被破坏。
~~~     这种表引擎的典型用法是 write-once:首先只写入一次数据,然后根据需要多次读取。
~~~     此引擎适用于相对较小的表(建议最多1,000,000行)。
~~~     如果有许多小表,则使用此表引擎是适合的,因为它需要打开的文件更少。
~~~     当拥有大量小表时,可能会导致性能低下。 不支持索引。
### --- 案例:创建一个TinyLog引擎的表并插入一条数据

hadoop01 :) create table t (a UInt16, b String) ENGINE=TinyLog;

CREATE TABLE t
(
    `a` UInt16,
    `b` String
)
ENGINE = TinyLog

Ok.
hadoop01 :) insert into t (a, b) values (1, 'abc');

INSERT INTO t (a, b) VALUES

Ok.
### --- 此时我们到保存数据的目录/var/lib/clickhouse/data/default/t中可以看到如下目录结构:

~~~     # a.binb.bin 是压缩过的对应的列的数据, sizes.json 中记录了每个 *.bin 文件的大小:
[root@hadoop01 ~]# ls /var/lib/clickhouse/data/default/t
a.bin  b.bin  sizes.json

[root@hadoop01 ~]# cat /var/lib/clickhouse/data/default/t/sizes.json 
{"yandex":{"a%2Ebin":{"size":"28"},"b%2Ebin":{"size":"30"}}}
三、log
### --- Log

~~~     Log与 TinyLog 的不同之处在于,«标记» 的小文件与列文件存在一起。
~~~     这些标记写在每个数据块上,并且包含偏移量,
~~~     这些偏移量指示从哪里开始读取文件以便跳过指定的行数。
~~~     这使得可以在多个线程中读取表数据。
~~~     对于并发数据访问,可以同时执行读取操作,而写入操作则阻塞读取和其它写入。
~~~     Log 引擎不支持索引。同样,如果写入表失败,则该表将被破坏,并且从该表读取将返回错误。
~~~     Log 引擎适用于临时数据,write-once 表以及测试或演示目的。
### --- StripeLog

~~~     该引擎属于日志引擎系列。
~~~     请在日志引擎系列文章中(https://clickhouse.tech/docs/zh/engines/table-engines/log-family/)
~~~     查看引擎的共同属性和差异。
~~~     在你需要写入许多小数据量(小于一百万行)的表的场景下使用这个引擎。
### --- 建表

~~~     # 查看建表请求的详细说明。
(https://clickhouse.tech/docs/zh/engines/table-engines/logfamily/stripelog/#createtable-query)
 
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 UPDATEALTER DELETE 操作。
# 读数据
带标记的文件使得 ClickHouse 可以并行的读取数据。
这意味着 SELECT 请求返回行的顺序是不可预测的。使用ORDER BY 子句对行进行排序。
### --- 使用示例

~~~     # 建表
hadoop01 :) CREATE TABLE stripe_log_table ( timestamp DateTime, message_type String, message String ) ENGINE = StripeLog;

CREATE TABLE stripe_log_table
(
    `timestamp` DateTime,
    `message_type` String,
    `message` String
)
ENGINE = StripeLog

Ok.
~~~     # 插入数据:

hadoop01 :) INSERT INTO stripe_log_table VALUES (now(),'REGULAR','The first regular message');

INSERT INTO stripe_log_table VALUES

Ok.
hadoop01 :) INSERT INTO stripe_log_table VALUES (now(),'REGULAR','The second regular message');

INSERT INTO stripe_log_table VALUES

Ok.
hadoop01 :) INSERT INTO stripe_log_table VALUES (now(),'WARNING','The first warning message');

INSERT INTO stripe_log_table VALUES

Ok.
~~~     我们使用两次 INSERT 请求从而在 data.bin 文件中创建两个数据块。
~~~     ClickHouse 在查询数据时使用多线程。
~~~     每个线程读取单独的数据块并在完成后独立的返回结果行。
~~~     这样的结果是,大多数情况下,输出中块的顺序和输入时相应块的顺序是不同的。例如:
hadoop01 :) SELECT * FROM stripe_log_table;

SELECT *
FROM stripe_log_table

┌───────────timestamp─┬─message_type─┬─message───────────────────┐
│ 2021-10-31 23:43:17 │ REGULAR      │ The first regular message │
└─────────────────────┴──────────────┴───────────────────────────┘
┌───────────timestamp─┬─message_type─┬─message────────────────────┐
│ 2021-10-31 23:43:32 │ REGULAR      │ The second regular message │
└─────────────────────┴──────────────┴────────────────────────────┘
┌───────────timestamp─┬─message_type─┬─message───────────────────┐
│ 2021-10-31 23:46:18 │ WARNING      │ The first warning message │
└─────────────────────┴──────────────┴───────────────────────────┘
### --- 对结果排序(默认增序):

hadoop01 :) SELECT * FROM stripe_log_table ORDER BY timestamp ;

SELECT *
FROM stripe_log_table
ORDER BY timestamp ASC

┌───────────timestamp─┬─message_type─┬─message────────────────────┐
│ 2021-10-31 23:43:17 │ REGULAR      │ The first regular message  │
│ 2021-10-31 23:43:32 │ REGULAR      │ The second regular message │
│ 2021-10-31 23:46:18 │ WARNING      │ The first warning message  │
└─────────────────────┴──────────────┴────────────────────────────┘
四、Memory
### --- Memory

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

~~~     Merge 引擎 (不要跟 MergeTree 引擎混淆) 本身不存储数据,
~~~     但可用于同时从任意多个其他的表中读取数据。 
~~~     读是自动并行的,不支持写入。
~~~     读取时,那些被真正读取到数据的表的索引(如果有的话)会被使用。
~~~     Merge 引擎的参数:一个数据库名和一个用于匹配表名的正则表达式。
### --- 案例:先建t1,t2,t3三个表,然后用 Merge 引擎的 t 表再把它们链接起来。

~~~     # 建表t1
hadoop01 :) create table t1 (id UInt16, name String) ENGINE=TinyLog;

CREATE TABLE t1
(
    `id` UInt16,
    `name` String
)
ENGINE = TinyLog

Ok.
~~~     # 建表t2

hadoop01 :) create table t2 (id UInt16, name String) ENGINE=TinyLog;

CREATE TABLE t2
(
    `id` UInt16,
    `name` String
)
ENGINE = TinyLog

Ok.
~~~     # 建表t3

hadoop01 :) create table t3 (id UInt16, name String) ENGINE=TinyLog;

CREATE TABLE t3
(
    `id` UInt16,
    `name` String
)
ENGINE = TinyLog

Ok.
~~~     # 在t1表中写入数据

hadoop01 :) insert into t1(id, name) values (1, 'first');

INSERT INTO t1 (id, name) VALUES

Ok.
~~~     # 在t2表中写入数据

hadoop01 :) insert into t2(id, name) values (2, 'second');

INSERT INTO t2 (id, name) VALUES

Ok.
~~~     # 在t3表中写入数据

hadoop01 :) insert into t3(id, name) values (3, 'i am in t3');

INSERT INTO t3 (id, name) VALUES

Ok.
~~~     # 创建t表

hadoop01 :) create table t (id UInt16, name String) ENGINE=Merge(currentDatabase(), '^t');

CREATE TABLE t
(
    `id` UInt16,
    `name` String
)
ENGINE = Merge(currentDatabase(), '^t')

Ok.
~~~     # 查看t表

hadoop01 :) select * from t;

┌─id─┬─name──┐
│  1 │ first │
└────┴───────┘

┌─id─┬─name───┐
│  2 │ second │
└────┴────────┘

┌─id─┬─name───────┐
│  3 │ i am in t3 │
└────┴────────────┘

 
 
 
 
 
 
 
 
 

Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
                                                                                                                                                   ——W.S.Landor

 

 

posted on   yanqi_vip  阅读(2)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示