列式存储浅析 | 青训营

128 阅读2分钟

这是我参与「第四届青训营 」笔记创作活动的第13天。 

列存与行存对比

  • 行存:按行写入数据,读取数据时需要读取不必要的列,适用于OLTP系统,适用于按记录读取数据,不利于大数据集聚合统汁操作,不利于数据压缩。
  • 列存:可以只读取请求的列,适用于OLAP系统,适用于按列读取数据,利于大数据集聚合统计操作,利于数据压缩,不适合小的数据集,因为每条数据存在冗余存储列的信息。

列式存储写流程

  • 案例 image.png
  • 案例中左侧是数据源文件,右侧是持久化后的文件。
  • 源文件中共有2个字段(列),100个记录(行),chunkwrite1字段的数据格式占4个字节,chunkwrite2字段的数据格式占8个字节。
  • 数据持久化时先存第一列再存第二列,同时记录每次持久化的起始和结束字段号。
    • 本案例起始字段是0,第一次持久化后到第400个字节(100✖4),第二次持久化后到第1200个字节(400+100✖8)。
  • 同时在内存中记录每次持久化的块元数据信息:包括数据类型,字段名,持久化到磁盘的起始字节位置,该次持久化数据占用总的字节数(作为下次持久化的起始字节位置)。
    • 元数据信息先存储在内存中,最后再源文件持久化结束后,追加存储到持久化后的数据末尾:包括每次持久化的元数据信息、每次持久化的行数、持久化总的字节数。 image.png
  • 最终持久化后的数据格式是:数据、元数据、元数据的偏移量(长度)。 image.png
  • 整个文件的元数据信息包括:Schema(源文件各个字段的名称)和 各个块元数据信息。

列式存储读流程

  1. 读取整个文件的元数据
  2. 根据元数据,获取各个字段的名称以及每个block中各个列信息
  3. 根据请求列以及块元数据信息,找到对应的块数据,并读取对应列数据
  4. 将读取到的数据拼成Record返回给调用方