这是我参与「第四届青训营 」笔记创作活动的第13天。
列存与行存对比
- 行存:按行写入数据,读取数据时需要读取不必要的列,适用于OLTP系统,适用于按记录读取数据,不利于大数据集聚合统汁操作,不利于数据压缩。
- 列存:可以只读取请求的列,适用于OLAP系统,适用于按列读取数据,利于大数据集聚合统计操作,利于数据压缩,不适合小的数据集,因为每条数据存在冗余存储列的信息。
列式存储写流程
- 案例
- 案例中左侧是数据源文件,右侧是持久化后的文件。
- 源文件中共有2个字段(列),100个记录(行),chunkwrite1字段的数据格式占4个字节,chunkwrite2字段的数据格式占8个字节。
- 数据持久化时先存第一列再存第二列,同时记录每次持久化的起始和结束字段号。
- 本案例起始字段是0,第一次持久化后到第400个字节(100✖4),第二次持久化后到第1200个字节(400+100✖8)。
- 同时在内存中记录每次持久化的块元数据信息:包括数据类型,字段名,持久化到磁盘的起始字节位置,该次持久化数据占用总的字节数(作为下次持久化的起始字节位置)。
- 元数据信息先存储在内存中,最后再源文件持久化结束后,追加存储到持久化后的数据末尾:包括每次持久化的元数据信息、每次持久化的行数、持久化总的字节数。
- 元数据信息先存储在内存中,最后再源文件持久化结束后,追加存储到持久化后的数据末尾:包括每次持久化的元数据信息、每次持久化的行数、持久化总的字节数。
- 最终持久化后的数据格式是:数据、元数据、元数据的偏移量(长度)。
- 整个文件的元数据信息包括:Schema(源文件各个字段的名称)和 各个块元数据信息。
列式存储读流程
- 读取整个文件的元数据
- 根据元数据,获取各个字段的名称以及每个block中各个列信息
- 根据请求列以及块元数据信息,找到对应的块数据,并读取对应列数据
- 将读取到的数据拼成Record返回给调用方