本文主要为您介绍如何通过表格存储的Go SDK创建全局二级索引、读取全局二级索引表中的数据、删除全局二级索引。

创建全局二级索引

  • 创建主表同时创建全局二级索引
    示例如下:
    func CreateTableWithGlobalIndexSample(client *tablestore.TableStoreClient, tableName string) {
        createTableRequest := new(tablestore.CreateTableRequest)
    
        tableMeta := new(tablestore.TableMeta)
        tableMeta.TableName = tableName
        tableMeta.AddPrimaryKeyColumn("pk1", tablestore.PrimaryKeyType_STRING)
        tableMeta.AddPrimaryKeyColumn("pk2", tablestore.PrimaryKeyType_INTEGER)
        tableMeta.AddDefinedColumn("definedcol1", tablestore.DefinedColumn_STRING)
        tableMeta.AddDefinedColumn("definedcol2", tablestore.DefinedColumn_INTEGER)
    
        indexMeta := new(tablestore.IndexMeta) // 新建索引表Meta
        indexMeta.AddPrimaryKeyColumn("definedcol1") // 指定主表的DEFINED_COL_NAME_1列作为索引表的PK
        indexMeta.AddDefinedColumn("definedcol2") // 指定主表的DEFINED_COL_NAME_2列作为索引表的属性列
        indexMeta.IndexName = "indexSample"
    
        tableOption := new(tablestore.TableOption)
        tableOption.TimeToAlive = -1 // 数据过期时间设置为永不过期
        tableOption.MaxVersion = 1 // 最大版本数为1(带索引表的主表只支持版本数为1)
        reservedThroughput := new(tablestore.ReservedThroughput)
    
        createTableRequest.TableMeta = tableMeta
        createTableRequest.TableOption = tableOption
        createTableRequest.ReservedThroughput = reservedThroughput
        createTableRequest.AddIndexMeta(indexMeta)
    
        _, err := client.CreateTable(createTableRequest)
        if err != nil {
            fmt.Println("Failed to create table with error:", err)
        } else {
            fmt.Println("Create table finished")
        }
    }
  • 单独创建全局二级索引
    您可以在一张已经存在的主表上创建全局二级索引表,示例如下:
    func CreateGlobalIndexSample(client *tablestore.TableStoreClient, tableName string) {
        indexMeta := new(tablestore.IndexMeta) // 新建索引表Meta
        indexMeta.AddPrimaryKeyColumn("definedcol1") // 指定主表的DEFINED_COL_NAME_1列作为索引表的PK
        indexMeta.AddDefinedColumn("definedcol2") // 指定主表的DEFINED_COL_NAME_2列作为索引表的属性列
        indexMeta.IndexName = "indexSample"
        indexReq := &tablestore.CreateIndexRequest{
            MainTableName:tableName, // 将索引表添加到主表上
            IndexMeta: indexMeta,
            IncludeBaseData: true, // 包含存量数据
        }
        /**
          通过将IncludeBaseData参数设置为true,新建索引表后会开启主表中存量数据的同步,之后可以通过索引表查询全部数据,
          同步时间跟数据量的大小有一定的关系
        */  
        resp, err := client.CreateIndex(indexReq)
        if err != nil {
            fmt.Println("Failed to create table with error:", err)
        } else {
            fmt.Println("Create index finished", resp)
        }
    }
    说明 当前在添加索引表时,支持索引表中包含以及不包含主表中已经存在的数据。当CreateInexRequest的最后一个参数为true时,即为包含存量数据,为false时,即为不包含存量数据。

删除全局二级索引

您可以删除主表上的全局二级索引表,示例如下:
func DeleteIndex(client *tablestore.TableStoreClient, tableName string, indexName string) { 
    deleteIndex := &tablestore.DeleteIndexRequest{ MainTableName:tableName, IndexName: indexName }
    resp, err := client.DeleteIndex(deleteIndex)

    if err != nil {
        fmt.Println("Failed to delete index:", err)
    } else {
        fmt.Println("drop index finished", resp)
    }

读取二级索引表中的数据

示例如下:
func GetRangeFromIndex(client *tablestore.TableStoreClient, indexName string) {
    getRangeRequest := &tablestore.GetRangeRequest{}
    rangeRowQueryCriteria := &tablestore.RangeRowQueryCriteria{}
    rangeRowQueryCriteria.TableName = indexName

    startPK := new(tablestore.PrimaryKey)
    startPK.AddPrimaryKeyColumnWithMinValue("pk1") // 索引表的第一主键
    startPK.AddPrimaryKeyColumnWithMinValue("pk2") // 索引表的第二主键
    startPK.AddPrimaryKeyColumnWithMinValue("pk3") // 索引表的第三主键
    endPK := new(tablestore.PrimaryKey)
    endPK.AddPrimaryKeyColumnWithMaxValue("pk1")
    endPK.AddPrimaryKeyColumnWithMaxValue("pk2")
    endPK.AddPrimaryKeyColumnWithMaxValue("pk3")
    rangeRowQueryCriteria.StartPrimaryKey = startPK
    rangeRowQueryCriteria.EndPrimaryKey = endPK
    rangeRowQueryCriteria.Direction = tablestore.FORWARD
    rangeRowQueryCriteria.MaxVersion = 1
    rangeRowQueryCriteria.Limit = 10
    getRangeRequest.RangeRowQueryCriteria = rangeRowQueryCriteria

    getRangeResp, err := client.GetRange(getRangeRequest)

    fmt.Println("get range result is ", getRangeResp)

    for {
        if err != nil {
            fmt.Println("get range failed with error:", err)
        }
        if len(getRangeResp.Rows) > 0 {
            for _, row := range getRangeResp.Rows {
                fmt.Println("range get row with key", row.PrimaryKey.PrimaryKeys[0].Value, row.PrimaryKey.PrimaryKeys[1].Value, row.PrimaryKey.PrimaryKeys[2].Value)
            }
            if getRangeResp.NextStartPrimaryKey == nil {
                break
            } else {
                fmt.Println("next pk is :", getRangeResp.NextStartPrimaryKey.PrimaryKeys[0].Value, getRangeResp.NextStartPrimaryKey.PrimaryKeys[1].Value, getRangeResp.NextStartPrimaryKey.PrimaryKeys[2].Value)
                getRangeRequest.RangeRowQueryCriteria.StartPrimaryKey = getRangeResp.NextStartPrimaryKey
                getRangeResp, err = client.GetRange(getRangeRequest)
            }
        } else {
            break
        }

        fmt.Println("continue to query rows")
    }
    fmt.Println("putrow finished")
}