“ Parquet 是一种支持嵌套结构的列式存储格式,非常适用于 OLAP 场景,按列存储和扫描。”
01
—
概述
数据存储是信息技术对您每天所需的数据内容(从应用到网络协议,从文档到媒体,从地址簿到用户首选项)进行归档、整理和共享的过程。数据存储是大数据的核心环节。
试想一下,计算机就像大脑一样。两者都有短期记忆和长期记忆。大脑通过前额叶皮层来处理短期记忆,而计算机则利用随机存取存储器(RAM)来处理短期记忆。
大脑和 RAM 都要在清醒的状态下处理并记住事务,并且在工作一会儿后会感到疲倦。大脑在睡眠时会将工作记忆转换为长期记忆,而计算机则在睡眠时将活动记忆转换为存储卷。计算机还会按类型来分配数据,就像大脑按语义、空间、情感或规程来分配记忆一样。
随着数据存储技术的发展,数据的存储也从非结构化到半结构化最后到结构化数据的演进。
02
—
数据存储模式
目前大数据存储有几种方案可供选择:行存储、列存储、行列混合存储。业界对这几种存储方案有很多争执,集中焦点是:谁能够更有效地处理海量数据,且兼顾安全、可靠、完整性。从目前发展情况看,关系数据库已经不适应这种巨大的存储量和计算要求,基本是淘汰出局。在已知的几种大数据处理软件中,Hadoop的HBase采用列存储,MongoDB是文档型的行存储,Lexst是二进制型的行存储。
下图描述行存、列存、行列混合存储的物理结构如下图所示。
一、行式存储模式
传统的关系型数据库,如 Oracle、DB2、MySQL、SQL SERVER 等采用行式存储法(Row-based),在基于行式存储的数据库中, 数据是按照行数据为基础逻辑存储单元进行存储的, 一行中的数据在存储介质中以连续存储形式存在。
存储方式如下图所示:
行存储适合非常典型的OLTP(On-Line Transaction Processing)应用场景。为什么这么说呢,因为OLTP应用场景有如下特点:
随机的增删改查操作。
需要在行中选取所有属性的查询操作。
需要频繁插入或更新的操作,其操作与索引和行的大小更为相关。
所以传统 OLTP 数据库通常采用的是行式存储。所有的列依次排列构成一行,以行为单位存储,再配合以 B+ 树或 SS-Table 作为索引,就能快速通过主键找到相应的行数据。而且OLTP 数据库大多数场景下是为增删改查一整行记录,显然把一行数据存在物理上相邻的位置是个很好的选择。
二、列式存储模式
列式存储(Column-oriented Storage)并不是一项新技术,最早可以追溯到 1983 年的论文 Cantor。然而,受限于早期的硬件条件和使用场景,主流的事务型数据库(OLTP)大多采用行式存储,直到近几年分析型数据库(OLAP)的兴起,列式存储这一概念又变得流行。
存储方式如下图所示:
对于 OLAP(Online Analytical Processing) 场景,一个典型的查询需要遍历整个表,进行分组、排序、聚合等操作,这样一来按行存储的优势就不复存在了。更糟糕的是,分析型 SQL 常常不会用到所有的列,而仅仅对其中某些感兴趣的列做运算,那一行中那些无关的列也不得不参与扫描。
列式存储就是为这样的需求设计的。同一列的数据被一个接一个紧挨着存放在一起,表的每列构成一个长数组。
总的来说,列式存储的优势一方面体现在存储上能节约空间(提高压缩率)、减少 IO,另一方面依靠列式数据结构做了计算上的优化。
三、行式存储于列式存储的区别
行存储的写入是一次完成。如果这种写入建立在操作系统的文件系统上,可以保证写入过程的成功或者失败,数据的完整性因此可以确定。列存储由于需要把一行记录拆分成单列保存,写入次数明显比行存储多,再加上磁头需要在盘片上移动和定位花费的时间,实际时间消耗会更大。所以,行存储在写入上占有很大的优势。
还有数据修改, 这实际也是一次写入过程。不同的是,数据修改是对磁盘上的记录做删除标记。行存储是在指定位置写入一次,列存储是将磁盘定位到多个列上分别写入,这个过程仍是行存储的列数倍。所以,数据修改也是以行存储占优。数据读取时,行存储通常将一行数据完全读出,如果只需要其中几列数据的情况,就会存在冗余列,出于缩短处理时间的考量,消除冗余列的过程通常是在内存中进行的。列存储每次读取的数据是集合的一段或者全部,如果读取多列时,就需要移动磁头,再次定位到下一列的位置继续读取。再谈两种存储的数据分布。由