1.MySQL引擎
MySQL表引擎可以与MySQL数据库中的数据表建立映射,并通过SQL向其发起远程查询, 包括SELECT和INSERT
它的声明方式如下:
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],
...
) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']);
其中各参数的含义分别如下:
·host:port表示MySQL的地址和端口。
·database表示数据库的名称。
·table表示需要映射的表名称。
·user表示MySQL的用户名。
·password表示MySQL的密码。
Mysql引擎简单示例
--ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause'])
CREATE table tb_mysql(
id Int16,
name String ,
age UInt8 ,
phone UInt16
)Engine= MySQL('linux01:3306', 'test', 'stu', 'root', 'root');
2.HDFS引擎
Clickhouse可以直接从HDFS中指定的目录下加载数据 , 自己根本不存储数据, 仅仅是读取数据
ENGINE = HDFS(hdfs_uri,format)
·hdfs_uri表示HDFS的文件存储路径;
·format表示文件格式(指ClickHouse支持的文件格式,常见的有 CSV、TSV和JSON等)
我们一般期望的是数据有其他方式写入到HDFS系统中, 使用CK的HDFS引擎加载处理分析数据.
这种形式类似Hive的外挂表,由其他系统直接将文件写入HDFS。通过HDFS表引擎的hdfs_uri和format参数分别与HDFS的文件路径、文件格式建立映射。其中,hdfs_uri支持以下几种常见的配置方法:
-
绝对路径:会读取指定路径的单个文件,例如/clickhouse/hdfs_table1。
-
通配符:匹配所有字符,例如路径为/clickhouse/hdfs_table/,则会读取/click-house/hdfs_table路径下的所有文件。
-
?通配符:匹配单个字符,例如路径为/clickhouse/hdfs_table/organization?.csv,则会读取/clickhouse/hdfs_table路径下与organization?.csv匹配的文件,其中?代表任意一个合法字符。
-
{M..N}数字区间:匹配指定数字的文件,例如路径为/clickhouse/hdfs_table/organization_{1..3}.csv,则会读取/clickhouse/hdfs_table/路径下的文件organization_1.csv、organization_2.csv和organization_3.csv。
HDFS引擎简单示例
--ENGINE = HDFS(URI, format)
CREATE TABLE tb_hdfs(
id Int16,
name String ,
age UInt8 ,
phone UInt32
)Engine=HDFS('hdfs://linux01:8020/ck_data/stu.csv','CSV');
3.File引擎
File表引擎能够直接读取本地文件的数据,通常被作为一种扩充手段来使用。例如:它可以读取由其他系统生成的数据文件,如果外部系统直接修改了文件,则变相达到了数据更新的目的;它可以将 ClickHouse数据导出为本地文件;它还可以用于数据格式转换等场景。除此以外,File表引擎也被应用于clickhouse-local工具
File引擎简单示例
--File(Format)
--方式一 需要将文件放到指定文件夹下
--(:Exception: File /var/lib/clickhouse/store/71d/71d0b665-58b5-4acf-b1d0-b66558b54acf//data.CSV doesn't exist. (FILE_DOESNT_EXIST))
CREATE table tb_file(
id Int16,
name String ,
age UInt8 ,
phone UInt16
)Engine=File(CSV);
--方式二 加载任意路径下的数据 导入本地数据
CREATE table tb_file02(
id Int16,
name String ,
age UInt8 ,
phone UInt16
)Engine=File(CSV);
clickhouse-client -q "insert into test.tb_file02 format CSV"< /data/stu.csv
cat /data/stu.csv | clickhouse-client -q "insert into test.tb_file02 format CSV"
--表函数 file
--file(path, format, structure)
select * from file('/data/stu.csv','CSV','id Int16,name String ,age UInt8 ,phone UInt32');
默认加载的是特定的文件夹,数据一定要在指定的文件夹下才会被加载
Exception: File `/data/stu.csv` is not inside `/var/lib/clickhouse/user_files`. (DATABASE_ACCESS_DENIED)
修改默认的数据加载的文件夹
vi /etc/clickhouse-server/config.xml
/path n下一个
<!-- Directory with user provided files that are accessible by 'file' table function. -->
<user_files_path>/</user_files_path>
重启服务
service clickhouse-server restart
4.Menory
Memory表引擎直接将数据保存在内存中,数据既不会被压缩也不会被格式转换,数据在内存中保存的形态与查询时看到的如出一辙。 正因为如此,当ClickHouse服务重启的时候,Memory表内的数据会全部丢失。所以在一些场合,会将Memory作为测试表使用,很多初学者在学习ClickHouse的时候所写的Hello World程序很可能用的就是Memory表。由于不需要磁盘读取、序列化以及反序列等操作,所以Memory表引擎支持并行查询,并且在简单的查询场景中能够达到与MergeTree旗鼓相当的查询性能(一亿行数据量以内)。Memory表的创建方法如下所示:
CREATE TABLE tb_memory (
id UInt64
)ENGINE = Memory() ;
5.Buffer引擎
Buffer表引擎完全使用内存装载数据,不支持文件的持久化存储,所以当服务重启之后,表内的数据会被清空。Buffer表引擎不是为了面向查询场景而设计的,它的作用是充当缓冲区的角色。假设有这样一种场景,我们需要将数据写入目标MergeTree表A,由于写入的并发数很高,这可能会导致MergeTree表A的合并速度慢于写入速度(因为每一次INSERT都会生成一个新的分区目录)。此时,可以引入Buffer表来缓解这类问题,将Buffer表作为数据写入的缓冲区。数据首先被写入Buffer表,当满足预设条件时,Buffer表会自动将数据刷新到目标表
ENGINE = Buffer(database, table, num_layers, min_time, max_time,
min_rows, max_rows, min_bytes, max_bytes)
其中,参数可以分成基础参数和条件参数两类,首先说明基础参数的作用:
-
database:目标表的数据库。
-
table:目标表的名称,Buffer表内的数据会自动刷新到目标表。
-
num_layers:可以理解成线程数,Buffer表会按照num_layers的数量开启线程,以并行的方式将数据刷新到目标表,官方建议设为16。
Buffer表并不是实时刷新数据的,只有在阈值条件满足时它才会刷新。阈值条件由三组最小和最大值组成。接下来说明三组极值条件参数的具体含义:
-
min_time和max_time:时间条件的最小和最大值,单位为秒,从第一次向表内写入数据的时候开始计算;
-
min_rows和max_rows:数据行条件的最小和最大值;
-
min_bytes和max_bytes:数据体量条件的最小和最大值,单位为字节。
根据上述条件可知,Buffer表刷新的判断依据有三个,满足其中任意一个,Buffer表就会刷新数据,它们分别是:
-
如果三组条件中所有的最小阈值都已满足,则触发刷新动作;
-
如果三组条件中至少有一个最大阈值条件满足,则触发刷新动作;
还有一点需要注意,上述三组条件在每一个num_layers中都是单独计算的。假设num_layers=16,则Buffer表最多会开启16个线程来响应数据的写入,它们以轮询的方式接收请求,在每个线程内,会独立进行上述条件判断的过程。也就是说,假设一张Buffer表的
max_bytes=100000000(约100 MB),num_layers=16,那么这张Buffer表能够同时处理的最大数据量约是1.6 GB。
create table xx(
id Int64
)engine=MergeTree
order by id ;
CREATE TABLE buffer_to_xx AS xx
ENGINE = Buffer(default, xx, 16, 10, 100, 10000, 1000000, 10000000, 100000000) ;
INSERT INTO TABLE buffer_to_xx SELECT number FROM numbers(1000000) ;
此时,buffer_to_xx内有数据,而目标表xx是没有的,因为目前不论从时间、数据行还是数据大小来判断,没有一个达到了最大阈值。所以在大致100秒之后,数据才会从buffer_to_xx刷新到xx。
可以在ClickHouse的日志中发现相关记录信息:
INSERT INTO TABLE buffer_to_xx SELECT number FROM xx(1000001) ;
数据直接被插入到表中
创建一个具有与'merge.hits'相同结构的'merge.hits_buffer'表,并使用Buffer引擎。写入此表时,数据会缓冲在RAM中,然后再写入“ merge.hits”表。创建了16个缓冲区。如果经过了100秒,或者已写入一百万行,或者已写入100 MB数据,则将刷新其中每个数据;或者同时经过10秒并写入10,000行和10 MB数据。例如,如果只写了一行,则无论如何,在100秒后它将被刷新。但是,如果已写入许多行,则将更快地刷新数据。
当服务器停止时,使用DROP TABLE或DETACH TABLE,缓冲区数据也将刷新到目标表。
您可以在数据库名称和表名称的单引号中设置空字符串。这表明没有目标表。在这种情况下,当达到数据刷新条件时,只需清除缓冲区。这对于将数据窗口保留在内存中可能很有用。
从缓冲区表读取数据时,将从缓冲区和目标表(如果有的话)中处理数据。请注意
l 缓冲区表不支持索引。换句话说,缓冲区中的数据已被完全扫描,这对于大型缓冲区而言可能很慢。(对于下级表中的数据,将使用其支持的索引。)
l 如果“缓冲区”表中的列集与从属表中的列集不匹配,则插入两个表中都存在的列子集。
l 如果类型与缓冲区表和从属表中的任一列都不匹配,则会在服务器日志中输入错误消息,并清除缓冲区。如果刷新缓冲区时从属表不存在,也会发生相同的情况。
l 如果需要对下级表和Buffer表运行ALTER,建议先删除Buffer表,对下级表运行ALTER,然后再次创建Buffer表。
l 如果服务器异常重启,缓冲区中的数据将会丢失。
l FINAL和SAMPLE对于缓冲区表不能正常工作。这些条件将传递到目标表,但不用于处理缓冲区中的数据。如果需要这些功能,建议从目标表读取时仅使用缓冲区表进行写入。
l 将数据添加到缓冲区时,缓冲区之一被锁定。如果同时从表执行读取操作,则会导致延迟。
l 插入到缓冲区表中的数据可能以不同的顺序和不同的块最终出现在从属表中。因此,很难使用Buffer表正确地写入CollapsingMergeTree。为了避免出现问题,可以将“ num_layers”设置为1。
l 如果目标表被复制,则写入缓冲区表时,复制表的某些预期特性会丢失。数据部分的行顺序和大小的随机变化会导致重复数据删除退出工作,这意味着不可能对复制表进行可靠的“仅一次”写入。
l 由于这些缺点,我们仅建议在极少数情况下使用Buffer表。
l 当在一个单位时间内从大量服务器接收到太多INSERT且无法在插入之前对数据进行缓冲的情况下,将使用Buffer表,这意味着INSERT不能足够快地运行。
l 注意,即使一次插入缓冲区表也没有意义。这样只会产生每秒几千行的速度,而插入更大的数据块则每秒会产生一百万行以上的速度(请参阅“性能”一节)。
6.Set引擎
Set表引擎是拥有物理存储的,数据首先会被写至内存,然后被同步到磁盘文件中。所以当服务重启时,它的数据不会丢失,当数据表被重新装载时,文件数据会再次被全量加载至内存。众所周知,在Set 数据结构中,所有元素都是唯一的。Set表引擎具有去重的能力,在数据写入的过程中,重复的数据会被自动忽略。然而Set表引擎的使用场景既特殊又有限,它虽然支持正常的INSERT写入,但并不能直接使用SELECT对其进行查询,Set表引擎只能间接作为IN查询的右侧条件被查询使用
Set表引擎的存储结构由两部分组成,它们分别是:
[num].bin数据文件:保存了所有列字段的数据。其中,num是 一个自增id,从1开始。伴随着每一批数据的写入(每一次INSERT),都会生成一个新的.bin文件,num也会随之加1。
tmp临时目录:数据文件首先会被写到这个目录,当一批数据写入完毕之后,数据文件会被移出此目录。
CREATE TABLE tb_set(
id Int16,
name String
)engine=Set;
--插入数据
insert into tb_set values(1,'zs'),(2,'ls');
drop table tb_set_source;
CREATE TABLE tb_set_source
(
`id` Int16,
`name` String,
`age` UInt8
)
ENGINE = Log ;
insert into tb_set_source values(1,'zs',18),(2,'ww',28),(3,'zl',38) ;
发现在数据库的目录下是还有对应的目录的,可见数据会被存储到磁盘上的
但是这个表是不允许直接查询的
正确的查询方法是将Set表引擎作为IN查询的右侧条件
SELECT * from tb_set_source where (id,name) in tb_set;
--注意in 的条件和tb_set中的字段要保持一致
SELECT * from tb_set_source where id in tb_set; --本次测试中这种错误