NoSQL-Column-HBase数据模型

前端之家收集整理的这篇文章主要介绍了NoSQL-Column-HBase数据模型前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

RDBS是行数据库,数据是按表一行一行进行存储的。HBase是列数据库,存储是按列来存储的(准确点应该是按照列簇来存储的)。谈到列库就不得不说Google的BigTable,HBase的数据模型和BigTable的数据模型相似的,HBase是它的开源版本而已。表是由行和列构成,行列的交叉点在RDBS是一个属性,在HBase中称为Cell。并且HBase的cell是版本化的。cell的内容是不可分割的字节数组。我们用{row,column,version}来表示一个Cell。

我们将Cell看成一个三元组,不同的rowcolumn可以构成一个新Cell,version不同可以构成一个新的Cell。rowcolumn一般是固定的,version是不断变化的。所以我们有理由相信HBase数据存储的方式是由rowcolumn确定的。这只是一个猜测了,下面在看HBase实际的视图。

Column

Row

version

version


概念视图

下面是HBase的例子。 有一个名为webtable的表,包含两个列族:contents和anchor。在这个例子里面,anchor有两个列 (anchor:cssnsi.com,anchor:my.look.ca),contents仅有一列(contents:html)。每个列有一个,它是可以重复的。

webtable

Row Key Time Stamp ColumnFamilycontents ColumnFamilyanchor
"com.cnn.www" t9 anchor:cnnsi.com= "CNN"
"com.cnn.www" t8 anchor:my.look.ca= "CNN.com"
"com.cnn.www" t6 contents:html= "<html>..."
"com.cnn.www" t5 contents:html= "<html>..."
"com.cnn.www" t3 contents:html= "<html>..."

表是HBase的基本管理单元,表按Row排序的。表的Schema只定义它的列簇。每个列簇可以有任意多个列;每个列可以包含任意多版本;没有插入过数据的列是空;列簇中的列是排序过的,并且一起存储。

列名

一个列名是由它的列族前缀和修饰符(qualifier)连接而成。例如列contents:html是列族contents,加冒号(:),再加修饰符html组成的。

行键

每个行有个Key来标示改行,是用来检索记录的主键。

列簇

列簇是表中某些列的构成的集合,这些列并不是实际上的列,只不过是由修饰符(qualifier)标示的虚拟列。一个列族所有列成员是有着相同的前缀。比如,列courses:historycourses:math都是 列族courses的成员.冒号(:)是列族的分隔符,用来区分前缀和列名。column 前缀必须是可打印的字符,剩下的部分(称为qualify),可以又任意字节数组组成。列族必须在表建立的时候声明。column就不需要了,随时可以新建。在物理上,一个的列族成员在文件系统上都是存储在一起。因为存储优化都是针对列族级别的,这就意味着,一个colimn family的所有成员的是用相同的方式访问的。

时间戳

时间戳就是version,用来表示行键与列簇对应的列值的版本,时间戳是64位整型,一般用系统时间(精确到毫秒)。

HBase的数据以字节数组(byte[])表示的(除了表名),因为概念视图中提到的行键、列名、时间戳都是转换为字节数组存储的。

HBase的表是按key排序的,所有的表都必须要有主键-key。

HBase的表不要求所以行的列簇都有数据,也没有必要。如果用户查询的行没有指定的列簇,返回为空。若一个请求为要获取t8时间的contents:html,他的结果就是空。相似的,若请求为获取t9时间的anchor:my.look.ca,结果也是空。

物理视图

在概念视图里,表被看成是一个稀疏的行的集合。很多行都没有完整的列簇。因此在物理上,它的是按列族存储的。这样带来的好处是增加新列簇,不需要对物理存储做任何调整,HBse新的列簇可以不经过声明直接加入一个列族。

上面的概念视图在物理上隐射到下面两个物理视图。

ColumnFamilyanchor

Row Key Time Stamp Column Familyanchor
"com.cnn.www" t9 anchor:cnnsi.com= "CNN"
"com.cnn.www" t8 anchor:my.look.ca= "CNN.com"

ColumnFamilycontents

Row Key Time Stamp ColumnFamily "contents:"
"com.cnn.www" t6 contents:html= "<html>..."
"com.cnn.www" t5 contents:html= "<html>..."
"com.cnn.www" t3 contents:html= "<html>..."

可以再简化一下((Row,Family: Column,Timestamp)=Value):

Row Key

ColumnFamily

key

<Time Stamp,ColumnFamily: qualifier =vlaue>

为什么将TimeStamp独立存储为一个列呢?时间戳是用户查询指定的,将时间戳独立存储,可以加快数据访问处理的速度。

对于用户查询,如果指定了时间戳,HBase返回指定Row Key&Column和Time Stamp对应的列值。否则选取指定 Row Key&Column中版本最高的Time Stamp的列值。如果没有指定列,则返回行键的所有满足条件的列值。例如,如果请求为获取行键为"com.cnn.www",没有指明时间戳的话,结果是t6下的contents:html,t9下的anchor:cnnsi.com和t8下anchor:my.look.ca。

数据模型操作

四个主要的数据模型操作是 Get,Put,Scan,和 Delete,仅能通过主键(row key)和主键的range来检索数据,通过HTable实例进行操作。没有更新操作,并且Delete也不是真正的删除,而是做一个标记,在表的合并拆分的时候处理。

Get,和 Delete操作可以通过HBase Shell和Java代码(REST,Thrift API)来进行。下面两个链接给出了简单是实例

http://blog.pureisle.net/archives/1887.html

http://blog.csdn.net/javaman_chen/article/details/7220216

HBase不通过Join支持,也没有事务支持,只是在行操作上有锁。

对于习惯了sql操作的人来说,HBase自身并没有提供sql支持,不过有一些开源项目可以提供,比如http://code.google.com/p/hbase-sql/。它们在一定程度上可以简化数据查询

猜你在找的NoSQL相关文章