HBASE-针对行键选择不同的查询

HBASE-针对行键选择不同的查询,hbase,arrow-keys,Hbase,Arrow Keys,我有一个名为“用户”的hbase表,rowkey由三部分组成: 用户ID 消息ID 时间戳 行键看起来像:${userid}{messageid}{timestamp} 假设我可以散列userid并固定字段长度,那么我是否可以执行类似SQL查询的查询: select distinct(userid) from users 如果rowkey不允许我这样查询,这是否意味着我需要创建一个只包含所有用户ID的单独表?我想如果我这样做,当我插入一条记录时,它将不再是原子的,因为我正在处理两个没有事务的表

我有一个名为“用户”的hbase表,rowkey由三部分组成:

  • 用户ID
  • 消息ID
  • 时间戳
  • 行键看起来像:
    ${userid}{messageid}{timestamp}

    假设我可以散列userid并固定字段长度,那么我是否可以执行类似SQL查询的查询:

    select distinct(userid) from users
    

    如果rowkey不允许我这样查询,这是否意味着我需要创建一个只包含所有用户ID的单独表?我想如果我这样做,当我插入一条记录时,它将不再是原子的,因为我正在处理两个没有事务的表

    您可以使用HashSet来实现这一点。大概是这样的:

    public Set<String> getDistinctCol(String tableName,String colFamilyName, String colName)
       {
        Set<String> set = new HashSet<String>();
        ResultScanner rs=null;
        Result r = null;
        String s = null;
        try 
        {
            HTable table = new HTable(conf, tableName);
            Scan scan = new Scan();
            scan.addColumn(Bytes.toBytes(colFamilyName),Bytes.toBytes(colName));
            rs = table.getScanner(scan);
            while((res=rs.next()) != null)
            {
                byte [] col = res.getValue(Bytes.toBytes(colFamilyName+":"+colName));                
                s = Bytes.toString(col);
                set.add(s);
            }
        } catch (IOException e) 
        {
            System.out.println("Exception occured in retrieving data");
        }
        finally
        {
            rs.close();
        }
        return set;
    
    public Set getDistinctCol(字符串tableName、字符串colFamilyName、字符串colName)
    {
    Set=newhashset();
    结果扫描程序rs=null;
    结果r=null;
    字符串s=null;
    尝试
    {
    HTable table=新的HTable(conf,tableName);
    扫描=新扫描();
    scan.addColumn(Bytes.toBytes(colFamilyName),Bytes.toBytes(colName));
    rs=表格。getScanner(扫描);
    while((res=rs.next())!=null)
    {
    byte[]col=res.getValue(Bytes.toBytes(colFamilyName+“:”+colName));
    s=字节数。toString(col);
    设置。添加(s);
    }
    }捕获(IOE异常)
    {
    System.out.println(“检索数据时发生异常”);
    }
    最后
    {
    rs.close();
    }
    返回集;
    
    *在您的例子中,col是userID


    HTH

    你可以这样做,但作为一个映射/减少工作,不是直接查询

    所以你建议我也保留userid作为一个列,然后在我想得到一组userid时进行一次完整的表扫描。这感觉有点贵。或者你也可以对rowkey做同样的事情。从每个rowkwy中提取userid部分并放入集合中。但是正如Arnon所说,没有直接的方法可以做到这一点。如果你不介意的话,我会给你一个建议。你为什么不使用Hive来做这类事情呢?那样会容易得多。它会节省很多时间,而且与SQL类似,如果你来自SQL背景,它会更舒适。你可以将数据存储在Hive warehouse中直接或映射现有的Hbase表,其中您已经有数据。我尝试在Hive上运行Hbase,正如您可能已经知道的,性能很差,因为它在下面映射。我需要实时响应,我正在考虑使用一个单独的Hbase表来存储用户。但正如我在原始问题中提到的,原子性是一个问题关注点。你是对的。但我们不能说Hive的性能很差。它的目的完全不同,即“批处理”而不是实时的东西。MR和Pig也是如此。如果你真的想让它成为实时的,你必须想一些替代方法,就像你上面所说的。这个解决方案在一个巨大的数据集的情况下会很麻烦,这通常是HBase的情况。