二級索引相當於把資料表的主鍵查詢能力擴充到了不同的列,當需要使用屬性查詢資料時,您可以通過建立二級索引加快資料查詢的效率。設定預定義列後,在建立二級索引時將預定義列作為索引表的索引列或者屬性列。建立二級索引後,您可以使用二級索引進行資料查詢。
前提條件
已建立資料表,且資料表的最大版本數(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);
}
常見問題
相關文檔
您還可以使用控制台或者命令列工具使用二級索引。更多資訊,請參見通過控制台使用二級索引和通過命令列工具使用二級索引。
如果需要更靈活豐富的資料加速查詢方式,例如多條件組合查詢、全文檢索索引、首碼查詢、模糊查詢等,您可以使用多元索引實現。更多資訊,請參見多元索引簡介。