
# 使用TableIndexer工具生成HBase本地二级索引
#### 操作场景
为了快速对数据创建索引，HBase提供了可通过MapReduce功能创建索引的TableIndexer工具，该工具可实现添加、构建和删除索引。具体使用场景如下：
- 在表中预先存在大量数据的情况下，可能希望在某个列上添加索引。但是使用addIndicesWithData() API添加索引会生成与相关数据对应的索引数据，这将花费大量时间。另一方面，使用addIndices()创建的索引不会构建与表数据对应的索引数据。因此，可以使用TableIndexer工具来完成索引的构建。
- 如果索引数据与表数据不一致，该工具可用于重新构建索引数据。 如果暂时禁用索引并且在此期间向禁用的索引列执行新的put操作，直接将索引从禁用状态启用可能会导致索引数据与表数据不一致。因此，必须在再次使用之前重新构建所有索引数据。
  

- 对于大量现有的索引数据，可以使用TableIndexer工具将索引数据从表中完全删除。
- 对于未建立索引的表，该工具允许同时添加和构建索引。
 
#### TableIndexer工具使用方法
- **添加新的索引到表** 中
  命令如下所示：
  **hbase org.apache.hadoop.hbase.hindex.mapreduce.TableIndexer -Dtablename.to.index=tablename -Dindexspecs.to.add='idx_0=\>** **cf_0** **:\[q_0-\>string\],\[q_1\];cf_1:\[q_2\],\[q_3\]#** *idx_1* **=\>cf_1:\[q_4\]'**
  相关参数如下:
  - **tablename.to.index**：表示创建索引的表名称。
  
  - **indexspecs.to.add**：表示索引名与对应表的列的映射关系。
  
  - **scan.caching**（可选）：包含一个整数值，表示在扫描数据表时将传递给扫描器的缓存行数。
  
  
  上述命令中的参数描述如下：
  - **idx_1**：表示索引名称。
  
  - **cf_0**：表示列族名称。
  
  - **q_0**：表示列名称。
  
  - **string**：表示数据类型，支持STRING，INTEGER，FLOAT，LONG，DOUBLE，SHORT，BYTE和CHAR。
  
  
  ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
  - "#"用于分隔索引，";"用于分隔列族，","用于分隔列限定符。
  
  - 列名及其数据类型应包含在"\[\]"中。
  
  - 列名及其数据类型通过"- \>"分隔。
  
  - 如果未指定具体列的数据类型，则使用默认数据类型（string）。
  
  - 如果未设置可选参数scan.caching，则将采用默认值1000。
  
  - 用户表必须存在。
  
  - 表中指定的索引不能存在。
  
  - 如果用户表中已经存在名称为'd'的ColumnFamily，则用户必须使用TableIndexer工具构建索引数据。
   
  在执行以上的命令之后，指定的索引将被添加到表中并且将处于INACTIVE状态，该行为与addIndices() API类似。
  

- **为用户表中的现有索引构建索引数据**
  该命令如下：
  **hbase org.apache.hadoop.hbase.hindex.mapreduce.TableIndexer -Dtablename.to.index=tablename -Dindexnames.to.build='idx_0#idx_1'**
  相关参数如下：
  - **tablename.to.index**：表示创建索引的表的名称。
  
  - **indexspecs.to.build**：表示索引名称。
  
  - **scan.caching**（可选）：包含一个整数值，表示在扫描数据表时将传递给扫描器的缓存行数。
  
  
  上述命令中的参数描述如下：
  - **idx_1**：表示索引名称
  
  
  ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
  - "#"用于分隔索引名称。
  
  - 如果未设置可选参数scan.caching，则将采用默认值1000。
  
  - 用户表必须存在。
   
  在执行以上的命令之后，指定的索引将被设置为ACTIVE状态。用户扫描数据时可以使用相关索引。
  
- **从用户表中删除现有索引及其数据**
  该命令如下：
  **hbase org.apache.hadoop.hbase.hindex.mapreduce.TableIndexer -Dtablename.to.index=tablename -Dindexnames.to.drop='idx_0#idx_1'**
  相关参数如下：
  - **tablename.to.index**：表示创建索引的表的名称。
  
  - **indexnames.to.drop**：表示应该和其数据一起删除的索引的名称（必须存在于表中）。
  
  - **scan.caching**（可选）：其中包含一个整数值，指示在扫描数据表时将传递给扫描器的缓存行数。
  
  
  上述命令中的参数描述如下：
  - **idx_1**：表示索引名称。
  
  
  ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
  - "#"用于分隔索引名称。
  
  - 如果未设置可选参数scan.caching，则将采用默认值1000。
  
  - 用户表必须存在。
   
  在执行前面的命令之后，指定的索引将从表中删除。
  
- **为用户表添加新的索引以及基于现有数据的数据构建**
  该命令如下：
  **hbase org.apache.hadoop.hbase.hindex.mapreduce.TableIndexer -Dtablename.to.index=tablename -Dindexspecs.to.add='idx_0 =\> cf_0：\[q_0-\> string\],\[q_1\];cf_1:\[ q_2\]，\[q_3\]#idx_1 =\> cf_1:\[q_4\]' -Dindexnames.to.build='idx_0'**
  ![](https://support.huaweicloud.com/cmpntguide-lts-mrs/public_sys-resources/note_3.0-zh-cn.png)
  - 用户表必须存在。
  
  - **indexspecs.to.add**中指定的索引不能已存在于表中。
  
  - **indexnames.to.build** 中指定的索引名称必须已经存在于表中，或者应该是**indexspecs.to.add**的一部分。
   
  在执行前面的命令之后，**indexspecs.to.add** 中指定的所有索引都将添加到该表中，并且将为通过**indexnames.to.build**为指定的所有索引构建索引数据。
  
 
