数据仓库实践杂谈(十二)——列式存储
[目录]
- 第一章:概述
- 第二章:整体数据分层
- 第三章:整体实现框架
- 第四章:元数据
- 第五章:ETL
- 第六章:数据校验
- 第七章:数据标准化
- 第八章:去重
- 第九章:增量/全量
- 第十章:拉链处理
- 第十一章:分布式处理增量
- 第十二章:列式存储
- 第十三章:逻辑数据模型(数仓模型)
- 第十四章:数据模型参考
- 第十五章:维模型
- 第十六章:渐变维
- 第十七章:数据回滚
- 第十八章:关于报表
- 第十九章:数据挖掘
数据仓库实践杂谈(十二)——列式存储
每个数据库都有自己特有的文件存储方式。对于一般的关系数据库,从逻辑上按列(字段)定义表的结构,按行存储每一条数据。很多年前,大概2004年,Sybase IQ就提出了专用于联机分析(OLAP)的列式存储机制。这是我记得最早采用列式存储的数据库了。之后,各数据库厂商,以及后来的开源大数据平台,在针对关系模型存储,或者类似关系模型存储都采用了列式存储方案。
回忆一下磁盘的存储方式,虽然我们一般都说随机存取,但实际上硬盘里面是按块存储的,每个块里面是像一条线那样顺序写进去。所以表格是二维的,存储是一维的。所谓随机读取,是你知道具体需要的数据所在的磁道、扇区,直接定位到位置读取。在行式存储结构下,就看出索引的好处了。建立了索引,就能根据索引直接定位到记录的开始,一口气把整条记录的数据都读出来。所以,行式存储的特点:
- 适合随机的增删改查操作;
- 需要在行中选取所有属性的查询操作;
- 需要频繁插入或更新的操作,其操作与索引和行的大小更为相关。
而对于大数据的分析场景来说,需要分析的表,比如订单,合同等,为了分析方便,往往会逆范式设计,把很多有关联的字段都放到一个表里面去,所以字段都会很多。但实际用的时候,往往只会用到小部分字段;而且会把所有记录的这个字段都拿出来,比如看订单金额的分布。
列式存储的好处主要体现在针对OLAP应用的查询效率提升上。包括:
-
数据压缩
同一列数据的类型是一样的,针对不同类型数据采用更高效的编码方式获得更高的压缩比。比如字符串类型采用字典表压缩(单独保存所有的字符串值以及对应的编号,实际表中保存对应值的编号)。压缩得好,存储空间小,IO效率自然提高。而且,虽然硬盘越来越不值钱,但数据能少占用空间总是好的。 -
延迟拼接
数据最终展现出来的时候是按照行显示的。在列式存储中,就需要把查询结果的多个字段拼接成一行。这本来是一个劣势,但被挖掘成一个优势,即延迟拼接。也就是先根据SQL语句中的条件字段过滤出符合条件的下标集合,根据下标集合过滤出需要提取的字段再进行合并。以此充分发挥列式存储的优势。 -
块遍历
列一般都是定长的。定长的数据可以像数组一样分配存储块,需要读取数据可以直接定位到对应的块中。
列式存储也广泛应用于Hadoop生态中。比如Hive的存储模式基本是先按行分块,并且保证一条记录中的所有字段都在一个块,读一条记录不需要跨域多个块。而块内,则按列存储。
而HBase则按行把表分为多个Region,每个region有一个或多个Store,每个Store保存一个Column Family。Store则根据Hdfs的块大小,分多个StoreFile。
了解存储结构有助于理解如何设计分布并行的数据处理方式。
未完待续。