Hbase最核心但也是最难理解的就是数据模型,由于与传统的关系型数据库不同,虽然Hbase也有表(Table),也有行(Row)和列(Column),但是与关系型数据库不同的是Hbase有一个列族(Column Family)的概念,它将一列或者多列组织在一起,HBase必须属于某一个列族。
行和列交叉点称为单元格(Cell),单元格时版本化的。单元格的内容,也就是列的值是不可分割的字节数组。
HBase没有数据类型,任何列值都被转换成字节数组进行存储。
HBase表中的行是通过行键(Rowkey)进行区分的。行键也是用来唯一确定一行的标识。
HBase中的行按Rowkey排序,排序方式采用字典顺序。
这些都是HBase的逻辑结果,他的物理结构也和传统关系型数据库有很大不同。
逻辑模型HBase的逻辑模型源自Google的BigTable模型。可以理解为一个稀疏的,长期存储的,多维度的和排序的映射表。
以下示例是 BigTable 论文第 2 页上的一个略微修改的形式。有一个名为webtable的表包含两行(com.cnn.www和com.example.www)和三个列族,名为contents,anchor和people。
在此示例中,对于第一行(com.cnn.www),anchor包含两列(anchor:cssnsi.com,anchor:my.look.ca),contents包含一列(contents:html)。此示例包含具有行键com.cnn.www的行的 5 个版本,以及具有行键com.example.www的行的一个版本。 contents:html列限定符包含给定网站的整个HTML。 anchor列族的限定符每个都包含指向该行所代表的站点的外部站点的链接,以及它在其链接的anchor中使用的文本。 people列系列表示与该站点关联的人员。
此表中看起来为空的单元格在 HBase 中不占用空间,或实际上不存在。这就是HBase“稀疏”的原因。表格视图不是查看 HBase 中数据的唯一方法,甚至也不是最准确的方法。以下表示与多维映射相同的信息。这只是一个出于演示目的的模型,可能并不完全准确。
{ "com.cnn.www": { contents: { t6: contents:html: "<html>..." t5: contents:html: "<html>..." t3: contents:html: "<html>..." } anchor: { t9: anchor:cnnsi.com = "CNN" t8: anchor:my.look.ca = "CNN.com" } people: {} } "com.example.www": { contents: { t5: contents:html: "<html>..." } anchor: {} people: { t5: people:author: "John Doe" } } } 物理模型虽然Hbase表可以看作一组稀疏的行,但在物理意义上它们是按照列族存储的。所以列是可以随时添加的。
Hbase是面向列的,存放行的不同列的物理文件,一个列族存放在多个HFile中,最重要的是一个列族的数据会被同一个Region管理。
空单元格不占据物理存储空间。因此,在时间戳t8处对contents:html列的值的请求将不返回任何值。类似地,在时间戳t9处对anchor:my.look.ca值的请求将不返回任何值。但是,如果未提供时间戳,则将返回特定列的最新值。给定多个版本,最新版本也是第一个版本,因为时间戳按降序存储。因此,如果没有指定时间戳,则对行com.cnn.www中所有列的值的请求将是:来自时间戳t6的contents:html的值,来自时间戳t9的anchor:cnnsi.com的值,来自时间戳t8的anchor:my.look.ca。
数据模型操作四个主要的数据模型操作是 Get,Put,Scan 和 Delete。通过实例化Table进行操作。
版本问题: Rowkey、Column(列族和列)、Version组合在一起称为Hbase中的一个单元格。
Rowkey和Column的值是用字节数组表示的,Version则是用一个长整型表示的。
Get操作返回指定行的属性,Get是在Scan基础上实现的。在默认情况下,如果没有指定版本,一旦使用Get操作,会返回最近版本的Cell。
要返回多个版本,需要设置Get.setMaxVersions()
要返回最新版本以外的其他版本,请参见 Get.setTimeRange()