HBase到底是列式存储还是行式存储?

逻辑概念上,数据库表是一种二维的数据结构,具有行和列。但在内存、磁盘等物理存储上,数据一般是需要线性顺序组织的。所以为了存储数据库表中的数据,有了两种常见的组织方式:基于行的存储和基于列的存储。

基于行的存储,是将整行数据连续存在一起。在基于行存储的表中,即使只需要读取指定列时,也需要先将对应行的数据读取到内存,然后再过滤目标列,这样会导致过多的磁盘IO、内存和时间开销,所以行式存储比较适用于每次需要访问完整行的场景。

基于列的存储,是将列数据连续存储在一起。因为是将相同类型的数据存储在了一起,往往压缩比比较高,从而也会降低磁盘IO、内存和时间开销,所以,列式存储适用于仅在单列或少数列上操作的场景。特别是在大数据时代,数据的列和行都比较多时候,列式存储优势会更加明显。但反过来,列式存储对于获取整行的请求效率就没那么高了,需要多次IO读取多个列的数据,然后再合并返回。

HBase表数据模型比较特别,也可以简单理解为有行和列的二维表,只是它的列称为“列族”,列族下面又可以在数据写入时指定很多的子列。另外,HBase物理存储上是将整个列族数据存储在一起的。所以,如果HBase中的一张表只有一个列族的话,等于是这个列族包含了这张表的所有列,也就是将表正行的数据连续存储在了一起,就等于是行式存储了。再比如,一张表有多个列族,并且每个列族下仅有一列(虽然HBase不建议这么做),也就是将表的列数据连续存储在了一起,就等于是列式存储了。