HBase一对多关系的表结构设计


    前面刚开始使用HBase只是用于存取某些简单的JAVA对象或是简单数据,所以一般设置列族和列标示时只用一个就行了。
    最近有个任务是把系统中的站内消息移到HBase当中去,才开始查HBase中的一对多关系,发现网上的资料讲的都不甚详尽,这篇blog记录一下我的设计和想法,这些想法毕竟未经证实,尚需验证。如果有大虾认为有不妥甚至错误的地方请不吝指教。

    首先讲两个我参考的资料,背景:一个主贴和N个回帖的一对多关系,学过一点数据库的应该都能体会到,图我就不画了:
1.官方推荐资料:
http://wiki.apache.org/hadoop/Hbase/DataModel
2.一位大大的简单HBase一对多表结构的介绍(感觉实际上他参考了资料1,不过讲的不太。。合理,而且下面列表的那个comment_title应该是写错了,一对多的那个例子貌似也让人很不解):
http://doudouclever.blog.163.com/blog/static/17511231020127893233972/

最终的解决方案是这个表(按照官方资料):
Table Row Key Family Attributes(ColumnKeys/Qualifiers)
BlogTable ID info: Author,Title,URL
text: No ColumnKey,3version
comment title: Column keys are written like YYYMMDDHHmmss. Should be IN-MEMORY and have a 1 version
comment author: Same keys. 1 Version
comment text: Same keys. 1 Version


因为刚开始看的是第二个资料,官方资料也没细看,导致理解偏差了。一直想明白这个一对多是怎么设计的,其实了解以下两个知识点就可以了:

1.HBase的二维表结构:三个重要概念是Column Family(以下简称为CF)和Column Key/Qualifier(以下简称为CK)还有RowKey。一个CF可以包含若干个CK。相当于CF是个合并单元格;CK才是具体的列标示,并且可以为空。Rowkey就是行标示,可以理解为主键。如下图所示:


2. Hbase中,对于某个Column Family中的Column Key是可以动态增加的

存储于关系型数据库中的数据如下,简单起见某些字段删减了:
表头
ID Author Title Body
1 张三 消息头 这是内容Hello World!


明细表:
ID HeadID CommentAuthor Title Body
1 1 李四 回复头1 这是回复内容1
2 1 王五 回复头2 这是回复内容2


转移到Hbase中存储,需要把以前的明细“纵向延伸”(对于同一表头,明细表一条一条向下加数据),转变为HBase的“横向延伸”(对同一RowKey,添加明细的ColumnKey),Hbase中存储的数据如下,iteye的表不会弄合并单元格,所以用excel截图来展示吧:



结论:从图中可以看出,HBase是 把以前关系数据库明细表的字段作为ColumnFamily,而 明细表的主键作为ColumnKey的这种结构来达到一对多的效果的。关系型数据库,明细增多时是纵向添加数据;对于Hbase,则是通过ColumnKey的增加来添加数据


由此可能产生的问题:
  • 1.HBase官方不推荐多Column Family,超过3个是妥妥儿不推荐的,原文见
  • http://hbase.apache.org/book/number.of.cfs.html
        可是一对多的这种关系是必须用多Column Family的,这点矛盾让我到现在还很不解。。
  • 2.RowKey的存储问题,传统数据库主键一般都是递增的方式生成的一批证书值,但是Hbase采用这种方式做为RowKey的话会导致regionserver负载过高的问题,所以RowKey的生成方式需要再讨论。
  • 3.这种一对多的方式,如果回复很多很多,比如贴吧随便一个帖子就是上W回复的,会导致ColumnKey变得很多,也就是说Hbase表会变得很宽=。= 
  •     尽管看过帖子说HBase并不是传统意义的二维结构,就是不会单独为某个Cell为空的区域留出空间存储数据(这里我可能理解和描述的都不太贴切), 总之这种“宽”的表结构,是对传统数据库表结构意识形态的一种冲击,不知道会不会有问题。。。

猜你喜欢

转载自wwwcomy.iteye.com/blog/1771285