
# 创建HBase表二级索引
#### 功能简介
一般都通过调用org.apache.hadoop.hbase.hindex.client.HIndexAdmin中方法进行HBase二级索引的管理，该类中提供了创建索引的方法。
![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
二级索引不支持修改，如果需要修改，请先删除旧的然后重新创建。
#### 代码样例
以下代码片段在com.huawei.bigdata.hbase.examples包的"HBaseSample"类的createIndex方法中。
```
public void createIndex() {
    LOG.info("Entering createIndex.");
    String indexName = "index_name";
    // Create hindex instance
    TableIndices tableIndices = new TableIndices();
    IndexSpecification iSpec = new IndexSpecification(indexName);
    iSpec.addIndexColumn(ColumnFamilyDescriptorBuilder.newBuilder(Bytes.toBytes("info")).build(),
            "name", ValueType.STRING);//注[1]
    tableIndices.addIndex(iSpec);
    HIndexAdmin iAdmin = null;
    Admin admin = null;
    try {
      admin = conn.getAdmin();
      iAdmin = HIndexClient.newHIndexAdmin(admin);
      // add index to the table
      iAdmin.addIndices(tableName, tableIndices);
      LOG.info("Create index successfully.");
    } catch (IOException e) {
      LOG.error("Create index failed " ,e);
    } finally {
      if (admin != null) {
          try {
            admin.close();
        } catch (IOException e) {
            LOG.error("Close admin failed " ,e);
        }
      }
      if (iAdmin != null) {
        try {
          // Close IndexAdmin Object
          iAdmin.close();
        } catch (IOException e) {
          LOG.error("Close admin failed " ,e);
        }
      }
    }
    LOG.info("Exiting createIndex.");
  }
```
新创建的二级索引默认是不启用的，如果需要启用指定的二级索引，可以参考如下代码片段。该代码片段在com.huawei.bigdata.hbase.examples包的"HBaseSample"类的enableIndex方法中。
```
public void enableIndex() {
        LOG.info("Entering createIndex.");
        // Name of the index to be enabled
        String indexName = "index_name";
        List<String> indexNameList = new ArrayList<String>();
        indexNameList.add(indexName);
        HIndexAdmin iAdmin = null;
        Admin admin = null;
        try {
            admin = conn.getAdmin();
            iAdmin = HIndexClient.newHIndexAdmin(admin);
            // Alternately, enable the specified indices
            iAdmin.enableIndices(tableName, indexNameList);
            LOG.info("Successfully enable indices {}  of the table {}", indexNameList, tableName);
        } catch (IOException e) {
            LOG.error("Failed to enable indices {}  of the table {} . {}", indexNameList, tableName, e);
        } finally {
            if (admin != null) {
                try {
                    admin.close();
                } catch (IOException e) {
                    LOG.error("Close admin failed ", e);
                }
            }
            if (iAdmin != null) {
                try {
                    iAdmin.close();
                } catch (IOException e) {
                    LOG.error("Close admin failed ", e);
                }
            }
        }
    }
```
#### 注意事项
注\[1\]：创建联合索引
HBase支持在多个字段上创建二级索引，例如在列name和age上。
```
HIndexSpecification iSpecUnite = new HIndexSpecification(indexName); 
 iSpecUnite.addIndexColumn(new HColumnDescriptor("info"), "name", ValueType.String); 
 iSpecUnite.addIndexColumn(new HColumnDescriptor("info"), "age", ValueType.String);
```
#### 相关操作
**使用命令创建索引表。**
您还可以通过TableIndexer工具在已有用户表中创建索引。
![](https://support.huaweicloud.com/devg3-mrs/public_sys-resources/note_3.0-zh-cn.png)
\<table_name\>用户表必须存在。
```
hbase org.apache.hadoop.hbase.hindex.mapreduce.TableIndexer -Dtablename.to.index=<table_name> -Dindexspecs.to.add='IDX1=>cf1:[q1->datatype];cf2:[q1->datatype],[q2->datatype],[q3->datatype]#IDX2=>cf1:[q5->datatype]' -Dindexnames.to.build='IDX1'
```
"#"用于区分不同的索引，";"用于区分不同的列族，","用于区分不同的列。
tablename.to.index：创建索引的用户表表名。
indexspecs.to.add：创建索引对应的用户表列。
其中命令中各参数的含义如下：
- IDX1：索引名称
- cf1：列族名称。
- q1：列名。
- datatype：数据类型。数据类型仅支持Integer、String、Double、Float、Long、Short、Byte、Char类型。
 
