二級索引支援在指定列上建立索引,產生的索引表中的資料按照指定的索引列進行排序,資料表的每一個資料寫入都會自動同步到索引表中。您只需向資料表中寫入資料,然後根據索引表進行查詢,在許多情境下能提高查詢的效率。
範例情境
在電話話單查詢情境下,每次使用者通話結束後,都會將此次通話的資訊記錄到該資料表中。
資料表的主鍵和預定義列如下:
CellNumber、StartTime作為資料表的主鍵,分別代表主叫號碼和通話發生時間。
CalledNumber、Duration和BaseStationNumber為資料表的預定義列,分別代表被叫號碼、通話時間長度和基站號碼。
資料表的範例資料請參見下表。Table Store的寬表模型是對所有行按照主鍵進行排序,並且提供順序掃描(GetRange)介面用於資料讀取。
CellNumber | StartTime(Unix時間戳記) | CalledNumber | Duration | BaseStationNumber |
123456 | 1532574644 | 654321 | 60 | 1 |
234567 | 1532574714 | 765432 | 10 | 1 |
234567 | 1532574734 | 123456 | 20 | 3 |
345678 | 1532574795 | 123456 | 5 | 2 |
345678 | 1532574861 | 123456 | 100 | 2 |
456789 | 1532584054 | 345678 | 200 | 3 |
假設如下查詢需求,請根據實際情況通過資料表、全域二級索引或者本地二級索引查詢所需資料。
查詢號碼234567的所有主叫話單
查詢號碼123456的被叫話單
查詢基站002從時間1532574740開始的所有話單
查詢發生在基站003上時間從1532574861到1532584054的所有通話記錄的通話時間長度
查詢發生在基站003上時間從1532574861到1532584054的所有通話記錄的總通話時間長度、平均通話時間長度、最大通話時間長度和最小通話時間長度
查詢主叫號碼456789到被叫號碼345678的所有話單
資料查詢
請根據查詢需求選擇合適的查詢方式。
實現方式
不同查詢需求的具體實現方式請參見下表說明。
關於建立表和二級索引的樣本請參見附錄:建立資料表和二級索引樣本。
建立資料表後需要寫入範例資料到資料表,資料表中的資料會自動同步到索引表中。關於寫入資料的具體操作,請參見寫入資料。
系統會自動進行索引列補齊,即把資料表的主鍵添加到索引列後,共同作為索引表的主鍵。
本地二級索引的第一個主鍵列必須與資料表的第一個主鍵列相同。
查詢需求 | 實現方式 |
查詢號碼234567的所有主叫話單 | 直接調用getRange介面對資料表進行掃描。 |
查詢號碼123456的被叫話單 | 在CalledNumber列上建立索引,然後調用getRange介面對索引表進行掃描。 |
查詢基站002從時間1532574740開始的所有話單 | 在BaseStationNumber和StartTime列上建立複合式索引,然後調用getRange介面對索引表(全域二級索引)進行掃描。 |
查詢發生在基站003上時間從1532574861到1532584054的所有通話記錄的通話時間長度 | 在BaseStationNumber和StartTime列上建立複合式索引,而且只把Duration列作為返回結果,然後調用getRange介面對索引表(全域二級索引)進行掃描。 您可以手動反查資料表擷取Duration列值或者將Duration列作為索引表的屬性列。 如果要查詢發生在基站003上時間從1532574861到1532584054的所有通話記錄的總通話時間長度、平均通話時間長度、最大通話時間長度和最小通話時間長度,您可以使用與本查詢需求相同的實現方式,然後對返回的每條通話時間長度做計算並得到最終結果。 說明 您也可以使用Table StoreSQL查詢,無需用戶端計算,直接使用SQL語句返回最終統計結果。更多資訊,請參見查詢資料。 |
查詢主叫號碼456789到被叫號碼345678的所有話單 | 在CellNumber列和CalledNumber列上建立複合式索引,而且將Duration列和BaseStationNumber列作為索引表的屬性列,然後調用getRange介面對索引表(本地二級索引)進行掃描。 |
查詢號碼234567的所有主叫話單
查詢號碼123456的被叫話單
查詢基站002從時間1532574740開始的所有話單
查詢發生在基站003上時間從1532574861到1532584054的所有通話記錄的通話時間長度
查詢主叫號碼456789到被叫號碼345678的所有話單
附錄:建立資料表和二級索引樣本
以下樣本用於建立本文中用到的資料表和二級索引(包括本地二級索引和全域二級索引)。
private static final String TABLE_NAME = "CallRecordTable";
private static final String INDEX0_NAME = "IndexOnBeCalledNumber";
private static final String INDEX1_NAME = "IndexOnBaseStation1";
private static final String INDEX2_NAME = "IndexOnBaseStation2";
private static final String INDEX3_NAME = "LocalIndexOnBeCalledNumber";
private static final String PRIMARY_KEY_NAME_1 = "CellNumber";
private static final String PRIMARY_KEY_NAME_2 = "StartTime";
private static final String DEFINED_COL_NAME_1 = "CalledNumber";
private static final String DEFINED_COL_NAME_2 = "Duration";
private static final String DEFINED_COL_NAME_3 = "BaseStationNumber";
private static void createTable(SyncClient client) {
TableMeta tableMeta = new TableMeta(TABLE_NAME);
tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME_1, PrimaryKeyType.INTEGER));
tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME_2, PrimaryKeyType.INTEGER));
tableMeta.addDefinedColumn(new DefinedColumnSchema(DEFINED_COL_NAME_1, DefinedColumnType.INTEGER));
tableMeta.addDefinedColumn(new DefinedColumnSchema(DEFINED_COL_NAME_2, DefinedColumnType.INTEGER));
tableMeta.addDefinedColumn(new DefinedColumnSchema(DEFINED_COL_NAME_3, DefinedColumnType.INTEGER));
//資料的到期時間, 單位秒, -1代表永不到期. 帶索引表的主表資料到期時間必須為-1。
int timeToLive = -1;
//儲存的最大版本數, 帶索引表的主表最大版本數必須為1。
int maxVersions = 1;
TableOptions tableOptions = new TableOptions(timeToLive, maxVersions);
ArrayList<IndexMeta> indexMetas = new ArrayList<IndexMeta>();
IndexMeta indexMeta0 = new IndexMeta(INDEX0_NAME);
indexMeta0.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
indexMetas.add(indexMeta0);
IndexMeta indexMeta1 = new IndexMeta(INDEX1_NAME);
indexMeta1.addPrimaryKeyColumn(DEFINED_COL_NAME_3);
indexMeta1.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
indexMetas.add(indexMeta1);
IndexMeta indexMeta2 = new IndexMeta(INDEX2_NAME);
indexMeta2.addPrimaryKeyColumn(DEFINED_COL_NAME_3);
indexMeta2.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
indexMeta2.addDefinedColumn(DEFINED_COL_NAME_2);
indexMetas.add(indexMeta2);
IndexMeta indexMeta3 = new IndexMeta(INDEX3_NAME);
indexMeta3.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1);
indexMeta3.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
indexMeta3.addDefinedColumn(DEFINED_COL_NAME_2);
indexMeta3.addDefinedColumn(DEFINED_COL_NAME_3);
//設定索引同步模式。
indexMeta3.setIndexUpdateMode(IUM_SYNC_INDEX);
//設定索引類型為IT_LOCAL_INDEX(本地二級索引)。
indexMeta3.setIndexType(IT_LOCAL_INDEX);
indexMetas.add(indexMeta3);
CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions, indexMetas);
client.createTable(request);
}