HBase行键设计:匹配两列中的任意一列

HBase row key design: matching either of two columns

我有一些数据包含列 colAcolB,等等。对于任何行,colAcolB 中的值都不同。

我收到类似 SELECT * FROM table WHERE colA = X or colB = X 的查询。为了优化,我在 MySQL.

中索引了 colAcolB

现在,我想在 HBase 中构建这个数据库,为相同的查询提供服务。但是我知道HBase没有索引,我需要设计好的行键。

我想到了这个方法:

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

有什么替代方法可以更 space 高效,同时保持性能?

您可以定义一个 HBase table,其列族的所有列都与您的 mysql table 相同。

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

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

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

事实上,即使您有办法用两个不同的列存储单个行(并执行您想要执行的查询),HBase 仍会在内部为每个列存储两次行键.查看我的回答 ,了解 HBase 如何在 HFile 中存储数据的示例。简而言之,HBase 将完整的行键与每个值一起存储(尽管前缀压缩负责分摊此成本)。您会在大多数列式数据库中找到类似的存储模型,主要是因为它们是列式的并且需要在每一列中存储行键。

所以,要回答你的问题,你的方法非常好。尽管我会将由定界符(而不是随机字符串)分隔的原始列标识符添加到行键,以防将来您只需要为其中一列设置 select 值。更好的是,将列标识符作为行键的前缀(而不是后缀),然后您可以传递行键过滤器(由 OR 分隔)并且您的设置可以扩展到任意数量的列,您可以 select列并仍然保持性能。

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