声明: 1. 本文为我的个人复习总结, 并非那种从零基础开始普及知识 内容详细全面, 言辞官方的文章
2. 由于是个人总结, 所以用最精简的话语来写文章
3. 若有错误不当之处, 请指出
列式存储, 使用LSM Tree结构, OLAP分析引擎, 不依赖于HDFS
在不进行join操作时, 速度碾压其他分析引擎; 在发生join操作时, 速度表现并不突出
整型
有符号
Int8, Int16, Int32, Int64
无符号
UInt8, UInt16, UInt32, UInt64
浮点型
Float32, Float64
布尔型
没有单独的布尔型, 可以使用 UInt8 类型代替, 取值限制为 0 和 1
Decimal类型
Decimal32, Decimal64, Decimal128
字符串类型
String
FixedString(N), 实际长度小于N时, 会被空字节填充
枚举类型
Enum8, Enum16
示例:
CREATE TABLE t_enum
(
-- 限制了这个只能存MONDAY 和 THUESDAY
WEEKDAY Enum8('MONDAY' = 1, 'THUESDAY' = 2)
)
ENGINE = TinyLog;
转为整数值:
SELECT CAST(x, 'Int8') FROM t_enum;
时间类型
Date
Datetime
Datetime64 年-月-日 时:分:秒.亚秒
数组类型
array(1, 2) 或 [1, 2]
引擎的名称大小写敏感
表引擎决定了如何存储表数据:
是为了分区间能够并行计算
数据其实是先写到临时分区, 后续才被合并到现有分区
分区目录: 由文件+索引文件+表定义文件
组成
它只提供了数据的一级索引
,但不是唯一约束
是稀疏索引(类似于跳表)
二级索引正在研发中, 目前尚未健全
数据的存活时间, 数据过期失效后不会立即清除
, 而是在合并时才进行清除, 被清除前这个数据依旧是可见的
它的清除不是为了业务去及时清除过期数据, 而只是为了节省内存才清除失效数据
设定了分区内
数据按照哪些字段 进行有序地保存
主键必须是order by字段的前缀字段, 比如 order by的字段是(id,sku_id)时, 那么主键必须是id 或者(id,sku_id)
可作ReplacingMergeTree里的去重字段
, 和SummingMergeTree里的维度字段
测试时使用, 不支持索引, 没有并发控制
基于内存, 速度快但可靠性低
支持索引和分区
create table t_order_mt(
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
) engine =MergeTree
partition by toYYYYMMDD(create_time)
primary key (id)
order by (id,sku_id);
相比于MergeTree多了分区内去重
的功能, 不会立即去重
, 而是在合并时才进行去重, 分区间是不去重的
它的去重不是为了业务去保证数据没有重复, 而只是为了节省内存才清除重复数据
order by的字段 作为去重字段
去重时, 保留版本字段值最大的, 如果版本字段相同则按插入顺序保留最后一条
-- create_time即版本字段
=ReplacingMergeTree(create_time)
对于不查询明细, 只关心最终聚合结果的场景, 适合使用SummingMergeTree, 有分区内预聚合
的功能, 分区间不会预聚合
order by的字段 作为维度字段, 进行后续聚合
其他列按插入顺序保留第一行
-- total_amount是聚合字段, 只是预聚合, 不是总聚合的最终结果, 求总聚合还是得sum(total_amount)
-- 若不指定聚合字段, 则把所有非维度字段 & 是数字类型的字段进行聚合
SummingMergeTree(total_amount)
ClickHouse提供了Delete和Update的能力, 这类操作被称为Mutation查询, 比较"重" 且不支持事务
-- delete
alter table t_order_smt delete where sku_id ='sku_001';
-- update
alter table t_order_smt update total_amount=toDecimal32(2000.00,2) where id =102;
因为比较"重", 所以只是临时给旧数据打上标记, 在分区发生合并的时候, 才删除旧数据来释放磁盘空间
with rollup: 从右至左去掉维度进行小计
with cube: 从右至左去掉维度进行小计,再从左至右去掉维度进行小计
with totals: 只计算合计
clickhouse-client --query "select * from t_order_mt" --format CSVWithNames > data.csv
目的是为了保障数据的高可靠性
ReplicatedMergeTree中:
第一个参数是分片的zk_path, 一般按照/clickhouse/table/{shard}/{table_name}
的格式写
第二个参数是副本名称, 相同的分片副本名称不能相同
副本虽然能保证数据的高可靠性, 但是每台Server还是要容纳一个副本里的全部数据
这时就要用到分片, 把一张表里的数据切成多份分给多台Server进行存储, 可以更好地利用有限的服务器资源
-- 创建本地表
create table st_order_mt on cluster gmall_cluster (
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
) engine =ReplicatedMergeTree('/clickhouse/tables/{shard}/st_order_mt','{replica}')
partition by toYYYYMMDD(create_time)
primary key (id)
order by (id,sku_id);
-- 创建分布式表(要用到本地表, 将其进行分片)
create table st_order_mt_all2 on cluster gmall_cluster
(
id UInt32,
sku_id String,
total_amount Decimal(16,2),
create_time Datetime
)engine = Distributed(gmall_cluster,default, st_order_mt,hiveHash(sku_id));
-- Distributed(集群名称,库名,本地表名,分片键)