前面刚开始使用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/
最终的解决方案是这个表(按照官方资料):
因为刚开始看的是第二个资料,官方资料也没细看,导致理解偏差了。一直想明白这个一对多是怎么设计的,其实了解以下两个知识点就可以了:
1.HBase的二维表结构:三个重要概念是Column Family(以下简称为CF)和Column Key/Qualifier(以下简称为CK)还有RowKey。一个CF可以包含若干个CK。相当于CF是个合并单元格;CK才是具体的列标示,并且可以为空。Rowkey就是行标示,可以理解为主键。如下图所示:
2. Hbase中,对于某个Column Family中的Column Key是可以动态增加的
存储于关系型数据库中的数据如下,简单起见某些字段删减了:
表头
明细表:
转移到Hbase中存储,需要把以前的明细“纵向延伸”(对于同一表头,明细表一条一条向下加数据),转变为HBase的“横向延伸”(对同一RowKey,添加明细的ColumnKey),Hbase中存储的数据如下,iteye的表不会弄合并单元格,所以用excel截图来展示吧:
结论:从图中可以看出,HBase是 把以前关系数据库明细表的字段作为ColumnFamily,而 明细表的主键作为ColumnKey的这种结构来达到一对多的效果的。关系型数据库,明细增多时是纵向添加数据;对于Hbase,则是通过ColumnKey的增加来添加数据
由此可能产生的问题:
最近有个任务是把系统中的站内消息移到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为空的区域留出空间存储数据(这里我可能理解和描述的都不太贴切), 总之这种“宽”的表结构,是对传统数据库表结构意识形态的一种冲击,不知道会不会有问题。。。