1.ROLAP:
创建事实表维度表和指标表,使用关联的方式进行sql关联,优点是灵活,缺点是数据量大以后,查询压力很大
2.MOLAP
预计算方式,在查询前提前将聚合的结果进行预计算处理,使用空间换取时间,缺点:占用空间,会有2的n次方组合;优点:速度快
3.HOLAP
等于MOLAP+ROLAP
由最开始的MySQL、oracle演变成Hadoop生态体系的hive;以spark分布式计算引擎查询,响应速度还是很慢。
依托MapReduce和spark进行预计算,将数据结果存入HBASE等高性能分布式数据库。响应速度很快,但是存在维度爆炸,数据同步实时性问题。
另辟蹊径,使用Elasticsearch搜索引擎来实现数据的聚合查询,在百万级数据的时候完全可以实现,但是数据量大后,力不从心。
具有ROLAP、在线实时查询、完整的DBMS、列存储、不需要预计算、批量更新、完善的sql和函数支持、不需要Hadoop的生态,开箱即用、支持高可用。
预先聚合的问题:
预先聚合只能支持固定的分析场景,所以无法满足自定义分析的需求。
维表组合会导致数据膨胀,造成不必要的计算和存储开销。
实时数据是实时接收的,预计算还要考虑如何进行实时更新数据。
实时聚合:
实时聚合虽然是完美但是意味着一切计算都是要动态、实时的。很难做到在极短的时间内返回数据。
在存储数据超过20万亿行的情况下,clickhouse能做到90%的查询在一秒内实现
随着数据量的正大,它的优势会更加明显。
不支持事务
不擅长根据主键按着行粒度进行查询
不擅长删除数据
列式存储和数据压缩
向量化执行引擎
关系模型和sql查询
多样化表引擎
多线程和分布式
多主架构
数据分片、分布式查询
整数、浮点数、定点数
常见的int(tinyint、Samallint、Int、BigInt)
clickhouse中的int类型(Int8/Int16/Int32、Int64)
Clickhouse支持无符号的数据(UInt8、UInt16、Uint32、Uint64)
常见是Float 代表单精度浮点数、double代表 双精度浮点数
clickhouse(Float32、Float64)
定点数
clickhouse(DEcimal132、Decimal164、Decimal1128)
代替传统的varchar、text、clob、Blob;string类型不限定字符集,可以存储任意编码,但是为了统一UTF-8约定
类似Char、但是和char不同的是char通常是用空格填充、FixedString是用null字节填充
常见的数据类型,如果
clickhouse目前没有时间戳类型,也就是最高精度是秒。如果想要毫秒、微妙只能借助Uint类型
包含年月日时分秒,支持字符串的形式写入
可以纪录亚秒,比如‘2022-02-02 00:00:00.00’
精确到天,支持字符串写入
同一类型
select array(1,2)
可以存储1到n个元素,允许不同的数据类型。
select tuple(-1,1,‘a’,now(),today()) as a ,toTypeName(a)
“(-1,1,‘a’,‘2023-03-13 09:44:43’,‘2023-03-13’)”,“Tuple(Int8, UInt8, String, DateTime, Date)”
定义表字段的时候,需要指明元素的类型,
create table tuple_test (
c1 Tuple(String,Int8)
) engine =Memory;
insert into tuple_test values ((‘a’,1))
主要是用来保障数据质量。
主要是定义常量包含(enum8 /enum16)
create table enum_test (
c1 ENUM8(‘one’=1,‘two’=2)
) engine =Memory;
insert into enum_test values (‘one’)
如果新增没有的值会报错
enum 和String的区别是:enum可以使用value进行排序分组去重
嵌套类型,只支持一层
create table nested_test (
name String,
age Int8,
dept Nested(
id String,
name String
)
) engine =Memory;
对于简单的层级关系和关联关系使用嵌套类型是不错的选择
insert into nested_test values (‘zs’,18,[‘dept1’,‘dept2’],[‘deptName1’,‘deptName2’]) ;
每个字段都是需要一个数组,每个数组个数要一致。
访问嵌套的类型
select dept.id
create table nested_test (
name Nullable(String),
age Int8
) engine =Memory;
是一个辅助的类型,需要和基础数据类型一起搭配使用。
只能和基础数据搭配使用,不能用于数组和元祖这些符合类型,也不能用在索引字段
nullable 会让查询和写入的性能变慢
域名类型分为IPv4和IPv6
create database if not exists db_test engine=Memory
数据库也支持引擎
五中引擎
在这个数据库下可以使用任意类型的表引擎
适用于一次写入多次读取,小于百万级别的小表
存放在内存中,服务重启后数据消失
会自动拉取MySQL的数据,并为他们创建MySQL引擎的数据表
数据分区,数据的一种纵向切分,借助数据分区跳过不必要的数据目录,从而提升查询的性能,还能变相的实现数据的更新操作。数据分区支持删除、替换和重置,假设按着月份分区,数据就可以按月份的粒度进行替换更新。
目前只有合并树(mergeTree)家族才支持数据分区。
create table db_test2.partition_table
(
id Int64 comment ‘主键’,
table_schema String comment ‘库名’,
etl_time datetime comment ‘时间’
) engine=MergeTree() partition by toYYYYMM(etl_time) order by id ;
select table,partition,path from system.parts where table=‘partition_table’;
SELECT * FROM partition_v1 WHERE EventTime =‘2019-05-01’
在后续的查询过程中,可以利用分区索引跳过6月份分区目录。
select table,partition,path from system.parts where table=‘partition_table’;
alter table partition_table drop partition 20190501
删除分区后再重新写入,可以达到更新的目的
两张表的表结构完全一致的情况并且都有分区键 可以复制分区
ALTER TABLE partition_v2 REPLACE PARTITION 201908 FROM partition_v1
INSERT INTO partition_v2 VALUES (‘A0014’,toString(1+2), now())
INSERT INTO partition_v2 FORMAT CSV
‘A0017’,‘www.nauu.com’, ‘2019-10-01’
‘A0018’,‘www.nauu.com’, ‘2019-10-01’
clickhouse有删除和修改的能力,但是不支持事务无法回滚,异步过程、很重的操作最好批量执行
删除
ALTER TABLE partition_v2 DELETE WHERE ID = ‘A003’
修改
ALTER TABLE partition_v2 DELETE WHERE ID = ‘A003’
CREATE [MATERIALIZED] VIEW [IF NOT EXISTS] [db.]table_name [TO[db.]name] [ENGINE = engine] [POPULATE] AS SELECT
物化视图创建好之后,如果源表被写入新数据,那么物化视图也会同步更新。POPULATE修饰符决定了
物化视图的初始化策略:如果使用了POPULATE修饰符,那么在创建视图的过程中,会连带将源表中已存在
的数据一并导入,如同执行了SELECT INTO一般;反之,如果不使用POPULATE修饰符,那么物化视图在创
建之后是没有数据的,它只会同步在此之后被写入源表的数据。物化视图目前并不支持同步删除,如果在
源表中删除了数据,物化视图的数据仍会保留。
数据会主动和被动加载到内存,并支持动态更新。字典数据常驻内存的特性,适合保存常亮和经常使用的维度表数据,避免不必要的join。
不常用
载config.xml中会配置默认识别架子啊/et/clickhouse-server目录下所有_.dictionary.xml结尾的配置文件
*_dictionary.xml
完整的配置结构
dict_name
字典的名称,唯一标识,全局唯一
字典的数据结构
或 -->
Id
...
数据结构是由键值key 和属性attribute组成,分别描述字典的数据标识和字段的属性。
数值型
使用ID配置 ,使用Uint64整数定义
Id
复合型使用tuple元组定义,类似数据库的复合主键
field1
String
field2
UInt64
省略…
Name
DataType
generateUUIDv4()
true
true
true
字典的类型,决定了数据在内存中以什么结构组织和存储
性能最高的字典类型,只能最多50万行数据。
完整的配置文件
test_flat_dict
id
code
String
name
String
300
360
只能使用Uint64数值型key,但是没有上限
range_hashed字典可以看作hashed字典的变种,它在原有功能的基础上增加了指定时间区间的特性,数据会以散列结构存储并按照时排序。时间区间通过range_min和range_max元素指定,所指定的字段必须是Date或者DateTime类型。
test_range_hashed_dict
id
start
end
price
Float32
300
360
查看字典
SELECT name, type, key, attribute.names, attribute.types FROM system.dictionaries
字典的数据源
本地文件
可执行文件
远程文件
mysql
·port:数据库端口。
·user:数据库用户名。
·password:数据库密码。
·replica:数据库host地址,支持MySQL集群。
·db:database数据库。
·table:字典对应的数据表。
·where:查询table时的过滤条件,非必填项。
·invalidate_query:指定一条SQL语句,用于在数据更新时判断是否需要更新
clickhouse
其中,各配置项的含义分别如下。
·host:数据库host地址。
·port:数据库端口。
·user:数据库用户名。
·password:数据库密码。
·db:database数据库。
·table:字典对应的数据表。
·where:查询table时的过滤条件,非必填项。
·invalidate_query:指定一条SQL语句,用于在数据更新时判断是否需要更新,非
mongoDB
test_mongodb_dict
字典的更新频率,秒
300
360
当都等于时禁止字典更新
当达到指定秒后,数据字典会进行更新。
对于文件类型会判断文件的修改时间,对于MySQL对根据
select updatetime from t_organization where id = 8
进行判断,如果两次的时间不一致,会进行全量更新。
在绝大多数的场景中都会用到这个表引擎。
高性能:列存储、自定义分区、稀疏的主索引
CREATE TABLE [IF NOT EXISTS] [db_name.]table_name (
name1 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
name2 [type] [DEFAULT|MATERIALIZED|ALIAS expr],
省略...
) ENGINE = MergeTree()
[PARTITION BY expr]
[ORDER BY expr]
[PRIMARY KEY expr]
[SAMPLE BY expr]
[SETTINGS name=value, 省略...]
(1)PARTITION BY [选填]:分区键,用于指定表数据以何种标
准进行分区。分区键既可以是单个列字段,也可以通过元组的形式使
用多个列字段,同时它也支持使用列表达式。如果不声明分区键,则
ClickHouse会生成一个名为all的分区。合理使用数据分区,可以有效
减少查询时数据文件的扫描范围,更多关于数据分区的细节会在6.2节
介绍。
(2)ORDER BY [必填]:排序键,用于指定在一个数据片段内,
数据以何种标准排序。默认情况下主键(PRIMARY KEY)与排序键相
同。排序键既可以是单个列字段,例如ORDER BY CounterID,也可以
通过元组的形式使用多个列字段,例如ORDER
BY(CounterID,EventDate)。当使用多个列字段排序时,以ORDER
BY(CounterID,EventDate)为例,在单个数据片段内,数据首先会以
CounterID排序,相同CounterID的数据再按EventDate排序。
(3)PRIMARY KEY [选填]:主键,顾名思义,声明后会依照主键
字段生成一级索引,用于加速表查询。默认情况下,主键与排序键
(ORDER BY)相同,所以通常直接使用ORDER BY代为指定主键,无须刻
意通过PRIMARY KEY声明。所以在一般情况下,在单个数据片段内,数
据与一级索引以相同的规则升序排列。与其他数据库不同,MergeTree
主键允许存在重复数据(ReplacingMergeTree可以去重)。
MergeTree数据分区规则是由分区键值决定的。四种规则
(1)不指定分区键:如果不使用分区键,即不使用PARTITION BY
声明任何分区表达式,则分区ID默认取名为all,所有的数据都会被写
入这个all分区。
(2)使用整型:如果分区键取值属于整型(兼容UInt64,包括有
符号整型和无符号整型),且无法转换为日期类型YYYYMMDD格式,则
直接按照该整型的字符形式输出,作为分区ID的取值。
(3)使用日期类型:如果分区键取值属于日期类型,或者是能够
转换为YYYYMMDD格式的整型,则使用按照YYYYMMDD进行格式化后的字
符形式输出,并作为分区ID的取值。
(4)使用其他类型:如果分区键取值既不属于整型,也不属于日
期类型,例如String、Float等,则通过128位Hash算法取其Hash值作
为分区ID的取值。
数据的存活时间
一定程度上可以去除重复数据
创建方式
ENGINE = ReplacingMergeTree(ver)
强制触发合并
optimize TABLE replace_table FINAL
(1)使用ORBER BY排序键作为判断重复数据的唯一键。
(2)只有在合并分区的时候才会触发删除重复数据的逻辑。
(3)以数据分区为单位删除重复数据。当分区合并时,同一分区
内的重复数据会被删除;不同分区之间的重复数据不会被删除。
(4)在进行数据去重时,因为分区内的数据已经基于ORBER BY进
行了排序,所以能够找到那些相邻的重复数据。
(5)版本号里面可以配置字段会根据字段保留最大值一条;不填是保留最后一条。
ENGINE = SummingMergeTree((col1,col2,…))
适用需求:只需要查询数据的汇总结果,不关心明细数据。
(1)用ORBER BY排序键作为聚合数据的条件Key。
(2)只有在合并分区的时候才会触发汇总的逻辑。
(3)以数据分区为单位来聚合数据。当分区合并时,同一数据分
区内聚合Key相同的数据会被合并汇总,而不同分区之间的数据则不会
被汇总。
(4)如果在定义引擎时指定了columns汇总列(非主键的数值类型
字段),则SUM汇总这些列字段;如果未指定,则聚合所有非主键的数
值类型字段。
(5)在进行数据汇总时,因为分区内的数据已经基于ORBER BY排
序,所以能够找到相邻且拥有相同聚合Key的数据。
(6)在汇总数据时,同一分区内,相同聚合Key的多行数据会合并
成一行。其中,汇总字段会进行SUM计算;对于那些非汇总字段,则会
使用第一行数据的取值。
数据立方体的概念,是SummingMergeTree的升级版,可以自定义聚合方式。
通常搭配MergeTree底表搭配使用
先创建底表
CREATE TABLE agg_table_basic(
id String,
city String,
code String,
value UInt32
)ENGINE = MergeTree()
PARTITION BY city
ORDER BY (id,city)
然后创建固化视图
CREATE MATERIALIZED VIEW agg_view
ENGINE = AggregatingMergeTree()
PARTITION BY city
ORDER BY (id,city)
AS SELECT
id,
city,
uniqState(code) AS code,
sumState(value) AS value
FROM agg_table_basic
GROUP BY id, city
新增数据到底表
INSERT INTO TABLE agg_table_basic
VALUES('A000','wuhan','code1',100),('A000','wuhan','code2',200),('A000','zhuhai', 'code1',200)
数据会自动的同步到物化视图,并按照aggregatingMErgeTree引擎进行规则处理
查询数据
SELECT id, sumMerge(value), uniqMerge(code) FROM agg_view GROUP BY id, city
(1)用ORBER BY排序键作为聚合数据的条件Key。
(2)使用AggregateFunction字段类型定义聚合函数的类型以及聚合的字段。
(3)只有在合并分区的时候才会触发聚合计算的逻辑。
(4)以数据分区为单位来聚合数据。当分区合并时,同一数据分区内聚合Key相同的数据会被合并计算,而不同分区之间的数据则不会被计算。
(5)在进行数据计算时,因为分区内的数据已经基于ORBER BY排序,所以能够找到那些相邻且拥有相同聚合Key的数据。
(6)在聚合数据时,同一分区内,相同聚合Key的多行数据会合并成一行。对于那些非主键、非AggregateFunction类型字段,则会使用第一行数据的取值。
(7)AggregateFunction类型的字段使用二进制存储,在写入数据时,需要调用State函数;而在查询数据时,则需要调用相应的Merge函数。其中,*表示定义时使用的聚合函数。
(8)AggregatingMergeTree通常作为物化视图的表引擎,与普通MergeTree搭配使用
支持增删的引擎,通过以增代删的思路进行行级别的修改和删除。定义一个sign标记位字段,如果数据航的状态是1标识是一条有效的数据;如果sign标记行是-1,标识数据需要被删除。
通过order by -1 和1 进行两两抵消,如果-1=1数量 ,这条数据消失。如果1>-1数量,修改操作保留1数据。
有个致命缺点是顺序不能乱,不能先-1在1
CREATE TABLE collpase_table(
id String,
code Int32,
create_time DateTime,
sign Int8
)ENGINE = CollapsingMergeTree(sign)
PARTITION BY toYYYYMM(create_time)
ORDER BY id
创建方式
CREATE TABLE ver_collpase_table(
id String,
code Int32,
create_time DateTime,
sign Int8,
ver UInt8
)ENGINE = VersionedCollapsingMergeTree(sign,ver)
PARTITION BY toYYYYMM(create_time)
ORDER BY id
加入版本的控制,不在局限于写入的顺序
只负责元数据管理和数据查询,数据文件由外部系统提供
创建方式
CREATE TABLE hdfs_table1(
id UInt32,
code String,
name String
)ENGINE = HDFS(‘hdfs://hdp1.nauu.com:8020/clickhouse/hdfs_table1’,‘CSV’)
format表示文件格式(指ClickHouse支持的文件格式,常见的有CSV、TSV
和JSON等)。
数据写入到clickhouse中后,同时会将数据以CSV的格式写到HDFS上,但是不支持是删除HDFS上文件。
ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause'])
其中各参数的含义分别如下:
·host:port表示MySQL的地址和端口。
·database表示数据库的名称。
·table表示需要映射的表名称。
·user表示MySQL的用户名。
·password表示MySQL的密码。
·replace_query默认为0,对应MySQL的REPLACE INTO语法。如果将它设置为1,则会用REPLACE
INTO代替INSERT INTO。
·on_duplicate_clause默认为0,对应MySQL的ON DUPLICATE KEY语法。如果需要使用该设置,
则必须将replace_query设置成0。
总结
提示:这里 对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。