在数据表上创建索引表后,可根据需要读取索引表中的数据或者删除数据表上指定的索引表。

使用

您可以使用如下语言的SDK实现全局二级索引功能。

创建索引表(CreateIndex)

使用CreateIndex接口在已存在的数据表上创建一个索引表。
说明 您也可以使用CreateTable接口在创建数据表的同时创建一个或者多个索引表。具体操作,请参见创建数据表
  • 参数
    参数 说明
    mainTableName 数据表名称。
    indexMeta 索引表的结构信息,包括如下内容:
    • indexName:索引表名称。
    • primaryKey:索引表的索引列,索引列为数据表主键和预定义列的组合。

      使用本地二级索引时,索引表的第一个主键列必须与数据表的第一个主键列相同。

    • definedColumns:索引表的属性列,索引表属性列为数据表的预定义列的组合。
    • indexType:索引类型。可选值包括IT_GLOBAL_INDEX和IT_LOCAL_INDEX。
      • 当不设置indexType或者设置indexType为IT_GLOBAL_INDEX时,表示使用全局二级索引。

        使用全局索引时,表格存储以异步方式将数据表中被索引的列和主键列的数据自动同步到索引表中,正常情况下同步延迟达到毫秒级别。

      • 当设置indexType为IT_LOCAL_INDEX时,表示使用本地二级索引。

        使用本地二级索引时,表格存储以同步方式将数据表中被索引的列和主键列的数据自动同步到索引表中,当数据写入数据表后,即可从索引表中查询到数据。

    • indexUpdateMode:索引更新模式。可选值包括IUM_ASYNC_INDEX和IUM_SYNC_INDEX。
      • 当不设置indexUpdateMode或者设置indexUpdateMode为IUM_ASYNC_INDEX时,表示异步更新。

        使用全局二级索引时,索引更新模式必须设置为异步更新(IUM_ASYNC_INDEX)。

      • 当设置indexUpdateMode为IUM_SYNC_INDEX时,表示同步更新。

        使用本地二级索引时,索引更新模式必须设置为同步更新(IUM_SYNC_INDEX)。

    includeBaseData 索引表中是否包含数据表中已存在的数据。

    当CreateIndexRequest中的最后一个参数includeBaseData设置为true时,表示包含存量数据;设置为false时,表示不包含存量数据。

  • 示例
    private static void createIndex(SyncClient client) {
        IndexMeta indexMeta = new IndexMeta(INDEX2_NAME); //设置索引表名称。
        indexMeta.addPrimaryKeyColumn(DEFINED_COL_NAME_1); //为索引表添加主键列,设置DEFINED_COL_NAME_1列为索引表的第一列主键。
        indexMeta.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2); //为索引表添加主键列,设置PRIMARY_KEY_NAME_2列为索引表的第二列主键。
        indexMeta.addDefinedColumn(DEFINED_COL_NAME_2); //为索引表添加属性列,设置DEFINED_COL_NAME_2列为索引表的属性列。
        //CreateIndexRequest request = new CreateIndexRequest(TABLE_NAME, indexMeta, true); //添加索引表到数据表,包含存量数据。
        CreateIndexRequest request = new CreateIndexRequest(TABLE_NAME, indexMeta, false); //添加索引表到数据表,不包含存量数据。
        /**通过将IncludeBaseData参数设置为true,创建索引表后会开启数据表中存量数据的同步,然后可以通过索引表查询全部数据,
           同步时间和数据量的大小有一定的关系。
        */
        //request.setIncludeBaseData(true);
        client.createIndex(request); //创建索引表。
    }

读取索引表中数据

从索引表中单行或者范围读取数据,当返回的属性列在索引表中时,可以直接读取索引表获取数据,否则请自行反查数据表获取数据。

  • 单行读取索引表中数据

    更多信息,请参见单行数据操作

    使用GetRow接口读取索引表中数据时有如下注意事项:
    • tableName需要设置为索引表名称。
    • 由于系统会自动将未出现在索引列中的数据表主键补齐到索引表主键中,所以设置行的主键时,需要同时设置索引表索引列和补齐的数据表主键。
  • 范围读索引表中数据

    更多信息,请参见多行数据操作

    • 参数
      使用GetRange接口读取索引表中数据时有如下注意事项:
      • tableName需要设置为索引表名称。
      • 由于系统会自动将未出现在索引列中的数据表主键补齐到索引表主键中,所以设置起始主键和结束主键时,需要同时设置索引表索引列和补齐的数据表主键。
    • 示例
      当需要返回的属性列在索引表中时,可以直接读取索引表获取数据。
      private static void scanFromIndex(SyncClient client) {
          RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX_NAME); //设置索引表名称。
      
          //设置起始主键。
          PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
          startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.INF_MIN); //设置需要读取的索引列最小值。
          startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN); //设置数据表主键最小值。
          startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MIN); //设置数据表主键最小值。
          rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());
      
          //设置结束主键。
          PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
          endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.INF_MAX); //设置需要读取的索引列最大值。
          endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX); //设置数据表主键最大值。
          endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX); //设置数据表主键最大值。
          rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());
      
          rangeRowQueryCriteria.setMaxVersions(1);
      
          System.out.println("扫描索引表的结果为:");
          while (true) {
              GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
              for (Row row : getRangeResponse.getRows()) {
                  System.out.println(row);
              }
      
              //如果nextStartPrimaryKey不为null,则继续读取。
              if (getRangeResponse.getNextStartPrimaryKey() != null) {
                  rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
              } else {
                  break;
              }
          }
      }
      当需要返回的属性列不在索引表中时,请自行反查数据表获取数据。
      private static void scanFromIndex(SyncClient client) {
          RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria(INDEX_NAME); //设置索引表名称。
      
          //设置起始主键。
          PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
          startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.INF_MIN); //设置需要读取的索引列最小值。
          startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN); //设置数据表主键最小值。
          startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MIN); //设置数据表主键最小值。
          rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());
      
          //设置结束主键。
          PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
          endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.INF_MAX); //设置需要读取的索引列最大值。
          endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX); //设置数据表主键最大值。
          endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MAX); //设置数据表主键最大值。
          rangeRowQueryCriteria.setExclusiveEndPrimaryKey(endPrimaryKeyBuilder.build());
      
          rangeRowQueryCriteria.setMaxVersions(1);
      
          while (true) {
              GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
              for (Row row : getRangeResponse.getRows()) {
                  PrimaryKey curIndexPrimaryKey = row.getPrimaryKey();
                  PrimaryKeyColumn pk1 = curIndexPrimaryKey.getPrimaryKeyColumn(PRIMARY_KEY_NAME_1);
                  PrimaryKeyColumn pk2 = curIndexPrimaryKey.getPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
                  PrimaryKeyBuilder mainTablePKBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
                  mainTablePKBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, pk1.getValue());
                  mainTablePKBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, ke2.getValue());
                  PrimaryKey mainTablePK = mainTablePKBuilder.build(); //根据索引表主键构造数据表主键。
      
                  //反查数据表。
                  SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, mainTablePK);
                  criteria.addColumnsToGet(DEFINED_COL_NAME_3); //设置读取数据表的DEFINED_COL_NAME_3列。
                  //设置读取最新版本。
                  criteria.setMaxVersions(1);
                  GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
                  Row mainTableRow = getRowResponse.getRow();
                  System.out.println(row); 
              }
      
              //如果nextStartPrimaryKey不为null,则继续读取。
              if (getRangeResponse.getNextStartPrimaryKey() != null) {
                  rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
              } else {
                  break;
              }
          }
      }

删除索引表(DeleteIndex)

使用DeleteIndex接口删除数据表上指定的索引表。

  • 参数
    参数 说明
    mainTableName 数据表名称。
    indexName 索引表名称。
  • 示例
    private static void deleteIndex(SyncClient client) {
        DeleteIndexRequest request = new DeleteIndexRequest(TABLE_NAME, INDEX_NAME); //设置数据表名称和索引表名称。
        client.deleteIndex(request); //删除索引表。
    }