1、 列式数据库
列式数据库(Columnar Databases)与行式数据库(Row-Oriented Databases)显著不同,需要具体场景具体分析:
列式数据库 以字段为中心,字段聚合效率优先,将同列数据连续存储(如ClickHouse),专为分析型负载(OLAP) 优化,典型应用于大数据分析、商业智能(BI)等需聚合海量数据的场景 。
行式数据库以记录为中心,记录完整性优先,将单行数据连续存储(如MySQL),适用于 高频率事务处理 ,例如电商交易、普通应用程序等快速读写完整记录的场景 。
2、 列式数据库的优点
同一列的所有值连续存储在磁盘块中,例如所有"学生成绩"字段集中存储 。
I/O效率高 :查询仅需读取相关列,避免加载冗余数据 。
压缩率显著 :同列数据同质性强(如均为整数),可采用RLE编码(重复值压缩)、字典编码(有限值域优化)、差值压缩(时序数据)等算法,压缩率达 8:1至60:1(行式数据库仅3:1-5:1)。
但列式数据库的单行更新需修改多个分散列块,事务效率低 。
3、 列式数据库的适合场景
大规模分析查询 :数据仓库、BI报表(如Apache Parquet + Spark)。
高压缩需求 :归档数据、物联网时序数据(压缩比>30:1)。
只读/低频更新:历史日志分析、批量数据处理。
4、clickHouse
ClickHouse 是一个开源的列式数据库管理系统(DBMS),专注于在线分析处理查询(OLAP)。Yandex公首次开源于2016年, 其主要用于在大数据的场景下进行实时的数据分析。可以见官网
在 1 亿数据级体量的情况下,ClickHouse 的平均响应速度是MySQL 的 429 倍,由此可见列式数据库在高数据量场景下的卓越性能。
性能数据比对详见:https://benchmark.clickhouse.com/
4.1 clickHouse数据存储与索引
根据官网教程(https://clickhouse.com/docs/guides/creating-tables)创建一张表:
java
CREATE TABLE helloworld.my_first_table
(
user_id UInt32,
message String,
timestamp DateTime,
metric Float32
)
ENGINE = MergeTree()
PRIMARY KEY (user_id, timestamp)
指定了一个复合主键(user_id, timestamp)
列字段相关的文件,每列都会有两个字段:
{column}.bin:列数据的存储文件,以列名+bin为文件名,默认设置采用 lz4 压缩格式;
{column}.cmrk:列数据的标记信息,记录了数据块在 bin 文件中的偏移量;
primary.cidx:这个是主键索引相关的文件的,用于存放稀疏索引的数据。通过查询条件与稀疏索引能够快速的过滤无用的数据,减少需要加载的数据量。
最小数据集 granule
表的列值在逻辑上被划分为 granule。多行数据为1 granule,granule 是为进行数据处理而流式传输到ClickHouse中的最小的不可分数据集。是始终读取(以流式传输方式并行读取)整个组(granule)行数据。每个 granule 分组的第一条数据会被写入到 primary.cidx 当作索引处理。
另外,有标记(.mrk)文件存储granule 在数据文件(.bin)中的存储位置。包含了两部分的信息,block offset 以及 granule offset。
因此,查询流程,先通过 primary.cidx 找到了对应数据所在 mark1,然后就可以对应的去 mrk 里面找对应的 block offset 和 granule offset。然后通过 block offset 找到该数据文件包含的压缩数据。文件块被解压缩到主内存中,随后granule offset 在未压缩的数据中定位对应的数据。
4.2 clickHouse联合主键查询
联合主键查询,与Mysql复合索引的最左原则类似,user_id, timestamp两个联合主键,如果where 条件里面只写了 user_id='xxx',可以使用二分查找法进行快速的索引;但如果只写了 timestamp='xxx',则会全表扫描。
4.3 clickHouse更新与删除
Clickhouse对update、delete的支持是比较弱,异步方式更新与删除,不保证原子性。
删除时 ,ClickHouse为删除的那一行的 _row_exists 列做标记,即逻辑删除,后续查询会排除已删除的行。
需要从磁盘中清理的,即物理删除,可以通过使用ALTER...DELETE操作:
java
alter table my_first_table delete where user_id= 1155
更新时, 主键的列或者排序键的值不能被更改,使用ALTER... UPDATE语句:
java
alter table my_first_table UPDATE message ='AAA' where user_id= 1155
4.4 clickHouse总结
clickHouse在单独某几列的查询速度非常快,数据可压缩,索引使用稀疏索引的方式占用空间少。无事务,更新删除效率低。
参考:
https://blog.csdn.net/m0_61505785/article/details/149630180
https://blog.csdn.net/glpghz/article/details/136003917
https://baijiahao.baidu.com/s?id=1775813809050392712\&wfr=spider\&for=pc
https://www.cnblogs.com/think90/p/11443311.html