表引擎:
TinyLog (生产环境不考虑 一般测试学习时使用)
以列文件的形式保存在磁盘上,不支持索引,没有并发控制,一般保存少量数据的小表
Memory (同理生产环境下不考虑使用)
内存引擎,数据以未压缩的原始形式保存在内存当中,服务器重启数据就会消失,同样的它也不支持索引,所有在简单的查询下会有非常高的i性能,一般用到的地方不多,大多都是用来测试,需要高性能,同时数据量又不大的场景下
Merge Tree (合并树家族 )***重点***
Clickhouse 中最强大的表引擎当属Merge Tree(合并树)引擎及该系列(*Merge Tree)中的其他引擎,支持索引和分区,地位可以相当于innodb之于Mysql
MergeTree 是以列文件+索引文件+表定义文件组成 如果设置了分区这些文件就会保存到不同的分区目录中
建表语句:
=========================================================================
create table t_order_mt(
id Ulnt32, (字段名加类型 Ulnt是无符号的INT型32位)
sku_id String,
total_amount Decimal(16.2),
create_time Datetime
)engine = MergerTree (这里指定表引擎)
partition by toYYYYMMDD(create_time) (分区字段 就跟HIVE一样 通常是按时间分区 这是把时间进行了转换 但是hive目录是在HDFS Clickhouse在磁盘)
(分区的作用:降低扫描的范围,优化查询速度 如果不填使用一个分区)
primary key (id) (主键 : 这里的主键并不唯一 没有唯一性是可以重复的)
order by (id,sku_id) (排序字段)
=========================================================================
当我们建完表以后我们可以通过磁盘地址查看这张表
cd /var/lib/clickhouse/ 命令 这里必须使用ROOT用户否则没权限
这里我们可以看到有很多了文件 这里我们需要注意的是data (中这里是表数据存储路径)和 metadata (表的结构信息)
这里data里面的两个文件 是我们的数据库名 然后我们进入后可以看到我们的表名
分区目录 20200601_1_1_0 第一个数值是代表最小分区块的编号 第二个数值是最大编号 第三个数值是合并等级
detached 是卸载 默认是空的
format_version.txt 是格式版本
数据就存在于 data.bin下 (mrk是标记文件) 这里因为版本差异 这个版本显示的是这样 (仅对当前引擎 合并树引擎)
这个就是这个分区里有几条数据 这也是它查询快的原因 因为它直接是记录好的
(这里因为我们提前插入了数据 建完表就插入了数据 如果没有插入数据这里是不存在的)
这一部分我们主要做一个了解:
Metadata 表数据结构 :
当我们进入到metadata目录下时:
我们同样可以看到两个虚拟机存在的数据库,进入后就可以查看库里存在的表:
这里SQL可以看到建表的SQL语句 也是后续查看表结构的基础
(这部分有一个了解就可以)
数据写入和分区合并:
任何一个批次的数据写入都会产生一个临时分区,不会纳入任何一个已有的分区,写入后的某个时刻,会自动合并操作
也可以手动操作直接合并 把临时分区的数据 合并到已有的分区中,合并语句:
Optimize table (表名) final;
这里我们二次插入数据会呈现这种情况:
这里我们可以看到 数据重复存在了 而且在不同的分区中(因为我们建表的时候确定的是按时间分区,所以我们可以看到 同一的时间在不同的分区 这里也是因为还没有进行合并导致的)
这里我们可以先看磁盘文件发生的变化:
我们可以看到分区增多了 但是我们也可以看到它的规律 根据上面所学的 我们可以进行一个解读
然后我们进行一个手动合并操作:
进行完以后我们看结果:
这里我们可以看到已经合并了
=========================================================================
而且我们可以看到我们建表时把ID设置为了主键 但是ID还是存在了重复出现的情况
这里就是它的主键不唯一性 跟以往的主键存在的差异
=========================================================================
但是在文件存储的地方 我们可以明显看到产生到的新文件
这里的文件 后续自动合并的时候 老文件会消失 保留最新文件 就相当于剔除了
手动合并优化语法:
当然这里我们也可以选择单个分区手动合并就是代码里加上partition
Optimize table 表名 partition 字段名(20200601) final;
这里我们讲一下 Primary key (主键 1.它不是唯一的可以重复 2.存在索引)
通过我们上面的操作可以得出结论:
Clickhouse的主键和其他数据库存在差异,它只提供了数据的一级索引,但是却不是唯一约束,这也就意味着时可以存在相同的Primary key的数据的
主键的设定主要是依据查询语句中的 WHERE条件
根据条件通过对主键进行二分查找,能够定位到对应的 index granularity(索引颗粒)(稀疏索引)避免了全表扫描
这里我们可以把它理解为他把索引部分也就是主键那部分 又分成了几个区间分区 当我们查找的时候根据WHERE条件 进行一个一级判定能够更准确快速的查找到相应区间分区数据
稀疏索引好处:
可以用很少的索引数据,定位更多的数据,代价就是只能定位到索引粒度的第一行,然后在进行一点扫描
拓展:二级索引
二级索引的功能在 20.1.24版本之前是被标注为实验型的,在这个版本之后是默认开启的,这里我们要注意
使用二级索引我们要在建表的时候就进行声明:及我们在根据我们上面的的建表语句的基础上:
create table t_order_mt2(
id Ulnt32, (字段名加类型 Ulnt是无符号的INT型32位)
sku_id String,
total_amount Decimal(16.2),
create_time Datetime
INDEX a total_amount TYPE minmax GRANULARITY 5
=========================================================================
这里我们重点关注 GRANULARITY 这里是设定二级索引对于一级索引颗粒的粒度
这里对接上面的稀疏索引:相当于把稀疏索引又进行了一次整合分区 形成了二层索引进一步优化查询速度
=========================================================================
)engine = MergerTree (这里指定表引擎)
partition by toYYYYMMDD(create_time) (分区字段 就跟HIVE一样 通常是按时间分区 这是把时间进行了转换 但是hive目录是在HDFS Clickhouse在磁盘)
(分区的作用:降低扫描的范围,优化查询速度 如果不填使用一个分区)
primary key (id) (主键 : 这里的主键并不唯一 没有唯一性是可以重复的)
order by (id,sku_id) (排序字段)
这个二级索引我们要看应用场景合理的应用
order by (这个是必须存在的)
这里我们记住一个最左匹配原则
order by 设定了分区内的数据按照那些字段进行排序进行有序保存
order by 是MergeTree 中唯一的一个必填项,甚至比primary key还重要,因为当用户不设定主键情况下,很多处理会依照order by 的字段进行处理 (比如后的的去重和汇总这里我们就不展开讲了)
这里注意如果如果需要设定主键 那么这个主键必须是order by 字段的前缀字段
就像我们上面 order by 字段是 id 和 sku_id 那么主键就必须是 id 或者是 id 和sku_id
这里就是最左匹配原则 主键必须是 order by 字段设定的最左边的那一个, 也就是第一个,否则就不成立 这一点尤为重要