Hbase搜索部分密钥?

时间:2012-10-16 05:56:03

标签: search join key hbase

为了更好地说明问题,我将从一个例子开始。可以说,你有3个表:

  • 学生(200万行)
  • TestResults(1亿行)
  • 测试(100 000行)。

我们将所有相关数据分组,并使用密钥添加名为“TestSynthesis”的非规范化表:TestID_StudentID_TestResultsID。密钥中字段的顺序无关紧要,因为用户需要能够搜索此密钥的任何或所有3个部分。

一个示例查询将是:“给我所有名字以'John'开头的学生的所有测试结果”

一个简单的解决方案是:

  1. 搜索规范化表格学生
  2. 提取学生ID(假设我们有3个ID:0001000,0000999,0000001)
  3. 然后在这些ID上搜索TestSynthesis(例如* 0001000 *,* 0000999 *,* 0000001 *)
  4. 但是,如果在第2步,我们得到100万行而不是3名学生呢?

    HBase可以仅搜索密钥(例如,不读取数据),还是需要进行全表扫描?

1 个答案:

答案 0 :(得分:13)

首先是痛苦的事实..正如其他帖子中所提到的,HBase并不完全支持部分密钥。让我们说你按照以下方式获得了密钥:正如你所提到的: TestID_StudentID_TestResultsID

您不能通过StudentID进行搜索,同时享受不错的表现。但是,有一种方法可以在扫描期间过滤行,只取决于行键。但请记住,过滤器的性能比良好的优化表模式差。因此,出于理解/经验,您有以下选择:

1)您尝试设计方案,以便针对大量查询进行优化。例如,大多数查询都需要给定学生的数据,因此您将studentID放在键的开头。有些查询需要知道当前学生的测试结果,然后使用{STARTROW => given_studentID,STOPROW => given_studentID + 1}进行扫描,并使用关键过滤器过滤得到的结果。可以设置关键过滤器以过滤特定的testID。但在这种情况下,如果你想看看哪些学生参加了测试,你需要进行全面扫描并对结果集应用过滤器,当我们讨论性能时,这不是很“便宜”。

2)如[http://stackoverflow.com/questions/12806762/hbase-data-only-in-key-compoung-key-wildcards] [1]中所述,您也可以将数据重复为两个不同的表,首先是TestID_StudentID_TestResultsID,第二个是这样的:StudentID_TestID_TestResultsID。通过这种方式,您可以通过给定的testID或StudentId进行查询,因为您可以在第一个或第二个表中愉快地搜索。如果您想知道哪个学生在所有测试中保持最佳结果,那么您将遇到麻烦。在这种情况下,您再次需要完整扫描。了解您将要使用哪种查询非常重要,这样您就可以适当地规划模式。 (你真的需要钥匙中的测试结果吗?)

3)还有第三种选择,我曾经使用过一次。这在很大程度上取决于数据本身。假设您将有50万名学生,大约50个测试,然后是50 * 500 000测试结果。在这种情况下,我将按以下方式设计架构: TestID_StudenIT_Results

*如果您想了解学生在特定考试中的表现,您可以根据考试进行扫描,因为密钥是从它开始的。

*如果你想看看学生在所有测试中的表现如何,你可以进行50次扫描,每次扫描使用开头的50个testID之一,这样扫描就像:

test1_studentX

test2_studentX

test3_studentX

test4_studentX

...

...

test50_studentX

50次扫描可能听起来太多,但它适合超级地图减少工作。这是一个问题,你真的有50个testID,或者你有适合的数字吗?

*如果您想了解所有学生在所有考试中的表现,您仍然需要使用此模式进行全面扫描。

那是我的!

欢呼声, 尼科