HBase行键设计:匹配两列之一

时间:2018-11-09 01:20:31

标签: mysql hbase

我有一些数据,其中包含列select code,'col1' as col_to_row, col1 as value, from database.table union all select code,'col2' as col_to_row, col2 as value, from database.table union all select code,'col3' as col_to_row, col3 as value, from database.table colA等。对于任何行,colBcolA中的值都是不同的。

我收到诸如colB之类的查询。为了进行优化,我在MySQL中索引了SELECT * FROM table WHERE colA = X or colB = XcolA


现在,我想在HBase中构建此数据库,并提供相同的查询。但是我了解HBase没有索引,因此我需要设计好的行键。

我想到了这种方法:

复制MySQL中的每一行。对于一个副本,请使用colB作为行键。对于其他,使用colA + randomString。 (附加随机字符串,因为每个行键必须唯一)。

  • 好:我只需要一个查询。即返回所有行键前缀为colB + randomString

  • 的行
  • 不好:我的数据库大小增加了一倍

在保持性能的同时,更节省空间的替代方法是什么?

2 个答案:

答案 0 :(得分:1)

您可以定义一个Hbase表,其中的列族的所有列均与mysql表相同。

HBase支持SingleColumnValueFilter过滤器,以根据列值过滤记录。您可以使用OR运算符比较ColA和ColB的值。

因此,无需在行键中添加任何前缀或后缀。

答案 1 :(得分:1)

您概述的方法足够好。 HBase是柱状的,可以使用前缀压缩,结合gzip块压缩可以确保磁盘上的大小实际上不是有用数据大小的两倍。

事实上,即使您有一种方法来存储包含两个不同列的一行(并执行您要执行的查询),HBase仍将在内部为每个列存储两次行键。请看我的答案here,以获取有关HBase如何在HFile中存储数据的示例。简而言之,HBase将完整的行键与每个单个值一起存储(尽管前缀压缩可分摊此费用)。您会在大多数列式数据库中找到类似的存储模型,这主要是因为它们是列式的,并且需要在每一列中存储行键。

因此,要回答您的问题,您的方法非常好。虽然我会在行键中添加由定界符(而不是随机字符串)分隔的原始列标识符,以防将来您仅需要为其中一列选择值。更好的是,将列标识符作为行键的前缀(而不是后缀),然后您可以通过行键过滤器(用OR分隔),并且设置可以缩放到任意数量的列,您可以在其中选择列的子集并保持性能。

查看它的另一种方法是使用HBase功能每秒进行数百万次写入,但在查询数据时仍保持原始关系视图。这实质上意味着您需要在感兴趣的列上创建二级索引。 Apache Phoenix在HBase之上为您提供所有这些;它是一个非常活跃的项目,并提供了两全其美的功能(HBase和SQL的写入强度很高,如数据过滤),并且增加了二级索引的存储成本(无论如何您都要在任何关系数据库中支付)。