HBase数据模型解析

HBase 是一种列存储模式与键值对存储模式结合的 NoSQL 数据库,它具有灵活的数据模型,不仅可以基于键进行快速查询,还可以实现基于值、列名等的全文遍历和检索。

HBase 可以实现自动的数据分片,用户不需要知道数据存储在哪个节点上,只要说明检索的要求,系统会自动进行数据的查询和反馈。

HBase 的基本概念

HBase 不支持关系模型,它可以根据用户的需求提供更灵活和可扩展的表设计。与传统的关系型数据库类似,HBase 也是以表的方式组织数据,应用程序将数据存于 HBase 的表中,HBase 的表也由行和列组成。

但有一点不同的是,HBase 有列族的概念,它将一列或多列组织在一起,HBase 的每个列必须属于某一个列族。

下面具体介绍 HBase 数据模型中一些名词的概念。

1) 表(Table)

HBase 中的数据以表的形式存储。同一个表中的数据通常是相关的,使用表主要是可以把某些列组织起来一起访问。表名作为 HDFS 存储路径的一部分来使用,在 HDFS 中可以看到每个表名都作为独立的目录结构。

2) 行(Row)

在 HBase 表里,每一行代表一个数据对象,每一行都以行键(Row Key)来进行唯一标识,行键可以是任意字符串。在 HBase 内部,行键是不可分割的字节数组,并且行键是按照字典排序由低到高存储在表中的。在 HBase 中可以针对行键建立索引,提高检索数据的速度。

3) 列族(Colunm Family)

HBase 中的列族是一些列的集合,列族中所有列成员有着相同的前缀,列族的名字必须是可显示的字符串。列族支持动态扩展,用户可以很轻松地添加一个列族或列,无须预定义列的数量以及类型。所有列均以字符串形式存储,用户在使用时需要自行进行数据类型转换。

4) 列标识(Column Qualifier)

列族中的数据通过列标识来进行定位,列标识也没有特定的数据类型,以二进制字节来存储。通常以 Column Family:Colunm Qualifier 来确定列族中的某列。

5) 单元格(Cell)

每一个行键、列族、列标识共同确定一个单元格,单元格的内容没有特定的数据类型,以二进制字节来存储。每个单元格保存着同一份数据的多个版本,不同时间版本的数据按照时间先后顺序排序,最新的数据排在最前面。单元格可以用 <RowKey,Column Family: Column Qualifier,Timestamp> 元组来进行访问。

6) 时间戳(Timestamp)

在默认情况下,每一个单元格插入数据时都会用时间戳来进行版本标识。读取单元格数据时,如果时间戳没有被指定,则默认返回最新的数据;写入新的单元格数据时,如果没有设置时间戳,默认使用当前时间。每一个列族的单元数据的版本数量都被 HBase 单独维护,默认情况下 HBase 保留 3 个版本数据。

数据模型

表是 HBase 中数据的逻辑组织方式,从用户视角来看,HBase 表的逻辑模型如表 1 所示。HBase 中的一个表有若干行,每行有多个列族,每个列族中包含多个列,而列中的值有多个版本。 

表 1 :HBase 逻辑数据模型
行键 列族 StuInfo 列族 Grades 时间戳
Name Age Sex Class BigData Computer Math
0001 Tom Green 18 Male   80 90 85 T2
0002 Amy 19   01 95   89 T1
0003 Allen 19 Male 02 90   88 T1

表 1 展示的是 HBase 中的学生信息表 Student,有三行记录和两个列族,行键分别为 0001、0002 和 0003,两个列族分别为 Stulnfo 和 Grades,每个列族中含有若干列,如列族 Stulnfo 包括 Name、Age、Sex 和 Class 四列,列族 Grades 包括 BigData、Computer 和 Math 三列。

在 HBase 中,列不是固定的表结构,在创建表时,不需要预先定义列名,可以在插入数据时临时创建。

从表 1 的逻辑模型来看,HBase 表与关系型数据库中的表结构之间似乎没有太大差异,只不过多了列族的概念。但实际上是有很大差别的,关系型数据库中表的结构需要预先定义,如列名及其数据类型和值域等内容。

如果需要添加新列,则需要修改表结构,这会对已有的数据产生很大影响。同时,关系型数据库中的表为每个列预留了存储空间,即表 1 中的空白 Cell 数据在关系型数据库中以“NULL”值占用存储空间。因此,对稀疏数据来说,关系型数据库表中就会产生很多“NULL”值,消耗大量的存储空间。

在 HBase 中,如表 1 中的空白 Cell 在物理上是不占用存储空间的,即不会存储空白的键值对。因此,若一个请求为获取 RowKey 为 0001 在 T2 时间的 Stulnfo:class 值时,其结果为空。类似地,若一个请求为获取 RowKey 为 0002 在 T1 时间的 Grades Computer 值时,其结果也为空。

与面向行存储的关系型数据库不同,HBase 是面向列存储的,且在实际的物理存储中,列族是分开存储的,即表 1 中的学生信息表将被存储为 Stulnfo 和 Grades 两个部分。

表 2 展示了 Stulnfo 这个列族的实际物理存储方式,列族 Grades 的存储与之类似。在表 2 中可以看到空白 Cell 是没有被存储下来的。

表 2:StuInfo 列族的物理存储方式
行键 列标识 时间戳
0001 Name TomGreen T2
0001 Age 18 T2
0001 Sex Male T2
0002 Name Amy T1
0002 Age 19 T1
0002 Class 01 T1
0003 Name Allen T1
0003 Age 19 T1
0003 Sex Male T1
0003 Class 02 T1