二級索引相當于把數據表的主鍵查詢能力擴展到了不同的列,當需要使用屬性查詢數據時,您可以通過創建二級索引加快數據查詢的效率。設置預定義列后,在創建二級索引時將預定義列作為索引表的索引列或者屬性列。創建二級索引后,您可以使用二級索引進行數據查詢。
前提條件
已創建數據表,且數據表的最大版本數(max Versions)必須為1,數據生命周期(Time to Live)必須滿足如下條件中的任意一個。
數據表的數據生命周期為-1(數據永不過期)。
數據表的數據生命周期不為-1時,數據表處于禁止更新狀態(即是否允許更新為否)。
二級索引的數據生命周期與數據表的數據生命周期相同。
步驟一:(可選)管理預定義列
使用二級索引時,如果未設置預定義列或者已有預定義列不滿足需求,您可以為數據表添加或者刪除預定義列。您可以使用Java SDK或者Go SDK管理預定義列,此處以Java SDK為例介紹預定義列的使用。
添加預定義列
以下示例用于為數據表增加預定義列,預定義列分別為definedColumnName01(String類型)、definedColumnName02(Integer類型)和definedColumnName03(String類型)。
public static void addDefinedColumnRequest(SyncClient client) {
AddDefinedColumnRequest addDefinedColumnRequest = new AddDefinedColumnRequest();
//設置數據表名稱。
addDefinedColumnRequest.setTableName("<TABLE_NAME>");
//為數據表添加預定義列。
addDefinedColumnRequest.addDefinedColumn("definedColumnName01",DefinedColumnType.STRING);
addDefinedColumnRequest.addDefinedColumn("definedColumnName02",DefinedColumnType.INTEGER);
addDefinedColumnRequest.addDefinedColumn("definedColumnName03",DefinedColumnType.STRING);
client.addDefinedColumn(addDefinedColumnRequest);
}
刪除預定義列
刪除數據表上不需要的預定義列。
以下示例用于刪除數據表的預定義列definedColumnName01和definedColumnName02。
public static void deleteDefinedColumnRequest(SyncClient client){
DeleteDefinedColumnRequest deleteDefinedColumnRequest = new DeleteDefinedColumnRequest();
//設置數據表名稱。
deleteDefinedColumnRequest.setTableName("<TABLE_NAME>");
//添加要刪除的預定義列。
deleteDefinedColumnRequest.addDefinedColumn("definedColumnName01");
deleteDefinedColumnRequest.addDefinedColumn("definedColumnName02");
client.deleteDefinedColumn(deleteDefinedColumnRequest);
}
步驟二:創建二級索引
使用CreateIndex接口在已存在的數據表上創建一個索引表用于加速數據查詢。二級索引包括全局二級索引和本地二級索引,請根據實際創建。
您也可以使用CreateTable接口在創建數據表的同時創建一個或者多個索引表。具體操作,請參見創建數據表。
您可以通過Java SDK、Go SDK、Python SDK、Node.js SDK、.NET SDK和PHP SDK創建二級索引,此處以Java SDK為例介紹二級索引的創建。
創建全局二級索引
以下示例用于為數據表創建一個全局二級索引。
private static void createIndex(SyncClient client) {
//設置索引表名稱。
IndexMeta indexMeta = new IndexMeta("<INDEX_NAME>");
//為索引表添加主鍵列,設置DEFINED_COL_NAME_1列為索引表的第一列主鍵。
indexMeta.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
//為索引表添加主鍵列,設置PRIMARY_KEY_NAME_2列為索引表的第二列主鍵。
indexMeta.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
//為索引表添加屬性列,設置DEFINED_COL_NAME_2列為索引表的屬性列。
indexMeta.addDefinedColumn(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);
}
創建本地二級索引
以下示例用于創建一個本地二級索引。
private static void createIndex(SyncClient client) {
//設置索引表名稱。
IndexMeta indexMeta = new IndexMeta("<INDEX_NAME>");
//為索引表添加主鍵列,設置PRIMARY_KEY_NAME_1列為索引表的第一列主鍵。
//本地二級索引的第一列主鍵必須與數據表的第一列主鍵相同。
indexMeta.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1);
//為索引表添加主鍵列,設置DEFINED_COL_NAME_1列為索引表的第二列主鍵。
indexMeta.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
//為索引表添加屬性列,設置DEFINED_COL_NAME_2列為索引表的屬性列。
indexMeta.addDefinedColumn(DEFINED_COL_NAME_2);
//設置索引類型為IT_LOCAL_INDEX(本地二級索引)。
indexMeta.setIndexType(IT_LOCAL_INDEX);
//設置同步模式為IUM_SYNC_INDEX(同步更新)。
indexMeta.setIndexUpdateMode(IUM_SYNC_INDEX);
//添加索引表到數據表,包含存量數據。
//CreateIndexRequest request = new CreateIndexRequest("<TABLE_NAME>", indexMeta, true);
//添加索引表到數據表,不包含存量數據。
CreateIndexRequest request = new CreateIndexRequest("<TABLE_NAME>", indexMeta, false);
/**通過將IncludeBaseData參數設置為true,創建索引表后會開啟數據表中存量數據的同步,然后可以通過索引表查詢全部數據,
同步時間和數據量的大小有一定的關系。
*/
//request.setIncludeBaseData(true);
//創建索引表。
client.createIndex(request);
}
步驟三:讀取索引表中數據
從索引表中單行或者范圍讀取數據,當返回的屬性列在索引表中時,您可以直接讀取索引表獲取數據,否則請自行反查數據表獲取數據。
您可以通過Java SDK、Go SDK、Python SDK、Node.js SDK、.NET SDK和PHP SDK讀取二級索引表中的數據,此處以Java SDK為例介紹二級索引的數據讀取。
單行讀取數據
讀取一行數據。
以下示例用于使用索引表讀取一行數據,設置讀取指定的列。
private static void getRowFromIndex(SyncClient client) {
//構造主鍵。如果讀取本地二級索引中的數據,索引表的第一列主鍵必須與數據表的第一列主鍵相同。
PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
primaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.fromString("def1"));
primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.fromLong(100));
primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.fromString("pri1"));
PrimaryKey primaryKey = primaryKeyBuilder.build();
//讀取一行數據,設置索引表名稱。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<INDEX_NAME>", primaryKey);
//設置讀取最新版本。
criteria.setMaxVersions(1);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row row = getRowResponse.getRow();
//如果讀取的行不存在,則返回值為null。
System.out.println("讀取完畢,結果為: ");
System.out.println(row);
//設置讀取某些列。
criteria.addColumnsToGet("Col0");
getRowResponse = client.getRow(new GetRowRequest(criteria));
row = getRowResponse.getRow();
System.out.println("讀取完畢,結果為:");
System.out.println(row);
}
范圍讀取數據
讀取指定主鍵范圍內的數據。
使用全局二級索引
當需要返回的屬性列在索引表中時,可以直接讀取索引表獲取數據。
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, pk2.getValue());
//根據索引表主鍵構造數據表主鍵。
PrimaryKey mainTablePK = mainTablePKBuilder.build();
//反查數據表。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", mainTablePK);
//設置讀取數據表的DEFINED_COL_NAME_3列。
criteria.addColumnsToGet(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;
}
}
}
使用本地二級索引
當需要返回的屬性列在索引表中時,可以直接讀取索引表獲取數據。
private static void scanFromIndex(SyncClient client) {
//設置索引表名稱。
RangeRowQueryCriteria rangeRowQueryCriteria = new RangeRowQueryCriteria("INDEX_NAME");
//設置起始主鍵。
PrimaryKeyBuilder startPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
//設置需要讀取的索引列最小值。
startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN);
//設置需要讀取的索引列最小值。
startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.INF_MIN);
//設置數據表主鍵最小值。
startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MIN);
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());
//設置結束主鍵。
PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
//設置需要讀取的索引列最大值。
endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX);
//設置需要讀取的索引列最大值。
endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_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(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MIN);
//設置需要讀取的索引列最小值。
startPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_NAME_1, PrimaryKeyValue.INF_MIN);
//設置數據表主鍵最小值。
startPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2, PrimaryKeyValue.INF_MIN);
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(startPrimaryKeyBuilder.build());
//設置結束主鍵。
PrimaryKeyBuilder endPrimaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
//設置需要讀取的索引列最大值。
endPrimaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1, PrimaryKeyValue.INF_MAX);
//設置需要讀取的索引列最大值。
endPrimaryKeyBuilder.addPrimaryKeyColumn(DEFINED_COL_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, pk2.getValue());
//根據索引表主鍵構造數據表主鍵。
PrimaryKey mainTablePK = mainTablePKBuilder.build();
//反查數據表。
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("TABLE_NAME", mainTablePK);
// 讀取主表的DEFINED_COL_NAME3列。
criteria.addColumnsToGet(DEFINED_COL_NAME3);
//設置讀取最新版本。
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;
}
}
}
附錄:刪除索引表
刪除不需要的索引表。
您可以通過Java SDK、Go SDK、Python SDK、Node.js SDK、.NET SDK和PHP SDK刪除二級索引,此處以Java SDK為例介紹二級索引的刪除。
以下示例用于刪除指定索引表。
private static void deleteIndex(SyncClient client) {
//設置數據表名稱和索引表名稱。
DeleteIndexRequest request = new DeleteIndexRequest("<TABLE_NAME>", "<INDEX_NAME>");
//刪除索引表。
client.deleteIndex(request);
}
常見問題
相關文檔
您還可以使用控制臺或者命令行工具使用二級索引。更多信息,請參見通過控制臺使用二級索引和通過命令行工具使用二級索引。
如果需要更靈活豐富的數據加速查詢方式,例如多條件組合查詢、全文檢索、前綴查詢、模糊查詢等,您可以使用多元索引實現。更多信息,請參見多元索引簡介。