跳到主要内容

行式存储与列式存储 ⭐️⭐️

理解 ⭐️⭐️

数据在磁盘上的存储格式,直接决定了数据查询和分析的效率。在Hadoop生态(如Hive)中,选择合适的底层数据存储文件格式是一项关键的性能优化手段。这与我们熟悉的MySQL等关系型数据库通过选择不同存储引擎(如InnoDB、MyISAM)来优化性能的思路异曲同工。

本文将通过一个简单的学生成绩表示例,深入探讨两种主流的数据存储方式:行式存储(Row-based Storage)列式存储(Column-based Storage)

下表为我们将要使用的学生成绩表示例:

一、行式存储 (Row-based Storage)

行式存储是最传统、最常见的数据组织方式。顾名思义,它将一行中的所有列数据连续地存储在一起。

数据组织结构:

采用行式存储时,数据在磁盘上的组织结构如下:

优点

  1. 行数据读写高效:由于一行的数据在物理上是连续存储的,因此进行整行数据的读取或写入(INSERT, UPDATE)时,I/O开销小,效率很高。这使其非常适合**OLTP(联机事务处理)**场景,如订单处理、用户注册等。
  2. 行重构成本低:当查询需要获取整行数据时(如 select * from tableA where id=''),一次I/O即可完成,无需额外计算。

缺点

  1. 分析查询效率低:当查询只涉及少数几列时,系统仍然需要读取整行数据,造成了大量的冗余I/O。例如,在 select name from tableA 的查询中,idscore 列的数据也被无效地读入了内存,大大降低了查询执行的效率。
  2. 压缩效率不高:一行中通常包含多种不同数据类型(字符串、数字、日期等),难以找到一种高效的算法对整行进行极致压缩。

二、列式存储 (Column-based Storage)

列式存储则将数据按列进行组织,同一列的所有数据被连续地存储在一起。

数据组织结构:

采用列式存储时,数据在磁盘上的组织结构如下:

优点

  1. 查询性能极高:查询时只需读取涉及的列,可以避免读取不必要的列,大大减少了I/O数据量。这特别适合OLAP(联机分析处理) 场景,如数据报表、用户行为分析等。
  2. 高压缩比:同一列的数据类型相同,数据特征相似,因此可以采用更高效的压缩算法(如Run-length encoding, Dictionary encoding),不仅节省存储空间,还能进一步减少查询时需要扫描的数据量。

缺点

  1. 行读写和更新效率低:当需要读取或写入一整行数据时,需要分别在多个列的存储文件中进行多次I/O操作,并将它们在内存中“重组”成一行,开销较大。尤其当一行的多个列不在一个HDFS块上时,网络开销和运算开销会非常显著。
  2. 不适合小批量、高频次的增删改操作

三、应用实例与技术选型

在实际应用中,不同的技术栈会根据其设计目标选择不同的存储模型。

  • 行式存储格式

    • Hive中TEXTFILESEQUENCEFILEAVRO 是典型的行式存储格式。
    • 传统关系型数据库:如 Oracle、DB2、MySQL、SQL Server 等,它们的核心引擎大多采用行式存储,以保证高效的事务处理能力。
  • 列式存储格式

    • Hive中RCFILEORCFILEPARQUET 是主流的列式存储格式,专为大数据分析场景优化。
    • 分布式数据库/数据仓库:新兴的 HBase、ClickHouse 等分布式数据库和数据仓库普遍采用列式存储,以实现极致的分析查询性能。

四、总结:如何选择?

行式存储与列式存储各有千秋,没有绝对的优劣,选择哪种格式取决于具体的业务场景。

特性行式存储 (Row-based)列式存储 (Column-based)
数据组织按行连续存储按列连续存储
适合场景OLTP (高频增删改查)OLAP (海量数据分析、聚合)
优点整行读写快,事务处理强只读所需列,查询快;压缩比高
缺点分析查询时I/O冗余大整行读写慢,更新成本高
典型应用MySQL, Oracle, SQL Server, AVROHBase, ClickHouse, Parquet, ORC