Indeks sekunder memungkinkan Anda mengkueri baris berdasarkan kolom selain kunci primer tabel data. Jika kueri berdasarkan kunci primer saja tidak dapat mengambil data yang dibutuhkan secara efisien, buatlah indeks sekunder pada kolom pradefinisi yang relevan untuk mempercepat pencarian. Setelah indeks dibuat, lakukan kueri langsung ke indeks tersebut alih-alih melakukan pemindaian penuh pada tabel data.
Prasyarat
Sebelum memulai, pastikan bahwa:
Tabel data memiliki Max Versions diatur ke 1.
TTL tabel data diatur ke -1 (data tidak pernah kedaluwarsa), atau parameter Allow Updates diatur ke No.
TTL indeks sekunder sama dengan TTL tabel data.
Langkah 1: (Opsional) Kelola kolom pradefinisi
Indeks sekunder hanya dapat menggunakan kolom yang dideklarasikan sebagai kolom pradefinisi saat tabel data dibuat. Jika tabel data tidak memiliki kolom pradefinisi atau kolom yang tersedia tidak sesuai dengan kebutuhan pengindeksan Anda, tambahkan atau hapus kolom pradefinisi sebelum membuat indeks.
Contoh berikut menggunakan Tablestore SDK for Java. Tablestore SDK for Go juga didukung.
Tambahkan kolom pradefinisi
Metode
public AddDefinedColumnResponse addDefinedColumn(AddDefinedColumnRequest addDefinedColumnRequest) throws TableStoreException, ClientException
Parameter
|
Parameter |
Tipe |
Deskripsi |
|
tableName (required) |
String |
Nama tabel data. |
|
definedColumns (required) |
List |
Informasi kolom pradefinisi. Setiap kolom pradefinisi berisi parameter berikut:
|
Kode contoh
Kode contoh berikut menambahkan kolom pradefinisi bertipe String bernama name ke test_table.
public static void addDefinedColumnExample(SyncClient client) {
AddDefinedColumnRequest addDefinedColumnRequest = new AddDefinedColumnRequest();
addDefinedColumnRequest.setTableName("test_table");
addDefinedColumnRequest.addDefinedColumn("name", DefinedColumnType.STRING);
client.addDefinedColumn(addDefinedColumnRequest);
}
Hapus kolom pradefinisi
Metode
public DeleteDefinedColumnResponse deleteDefinedColumn(DeleteDefinedColumnRequest deleteDefinedColumnRequest) throws TableStoreException, ClientException
Parameter
|
Parameter |
Tipe |
Deskripsi |
|
tableName (required) |
String |
Nama tabel data. |
|
definedColumns (required) |
List<String> |
Nama kolom pradefinisi yang akan dihapus. |
Kode contoh
Kode contoh berikut menghapus kolom pradefinisi bernama name dari test_table.
public static void deleteDefinedColumnExample(SyncClient client) {
DeleteDefinedColumnRequest deleteDefinedColumnRequest = new DeleteDefinedColumnRequest();
deleteDefinedColumnRequest.setTableName("test_table");
deleteDefinedColumnRequest.addDefinedColumn("name");
client.deleteDefinedColumn(deleteDefinedColumnRequest);
}
Langkah 2: Buat indeks sekunder
Panggil operasi CreateIndex untuk membuat tabel indeks pada tabel data yang sudah ada guna mempercepat kueri data. Indeks sekunder terbagi menjadi dua jenis: indeks sekunder global dan lokal. Pilih jenis yang sesuai dengan kebutuhan bisnis Anda.
Anda juga dapat membuat satu atau beberapa tabel indeks secara bersamaan dengan tabel data melalui operasi CreateTable. Untuk informasi lebih lanjut, lihat Buat tabel data.
Contoh berikut menggunakan Tablestore SDK for Java. SDK berikut juga didukung: Go, Python, Node.js, .NET, dan PHP.
Buat indeks sekunder global
Kode contoh berikut membuat indeks sekunder global. Indeks ini menggunakan DEFINED_COL_NAME_1 sebagai kolom kunci primer pertamanya dan PRIMARY_KEY_NAME_2 sebagai kolom kedua. DEFINED_COL_NAME_2 disertakan sebagai kolom atribut sehingga dapat dibaca langsung dari indeks tanpa perlu mencari di tabel data.
Atur IncludeBaseData ke true untuk menyertakan baris tabel data yang sudah ada ke dalam indeks. Waktu yang diperlukan untuk mengisi ulang data yang sudah ada bervariasi tergantung pada volume data.
private static void createIndex(SyncClient client) {
IndexMeta indexMeta = new IndexMeta("<INDEX_NAME>");
// Atur DEFINED_COL_NAME_1 sebagai kolom kunci primer pertama indeks.
indexMeta.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
// Atur PRIMARY_KEY_NAME_2 sebagai kolom kunci primer kedua indeks.
indexMeta.addPrimaryKeyColumn(PRIMARY_KEY_NAME_2);
// Sertakan DEFINED_COL_NAME_2 sebagai kolom atribut untuk pembacaan langsung dari indeks.
indexMeta.addDefinedColumn(DEFINED_COL_NAME_2);
// Buat indeks tanpa mengisi ulang data yang sudah ada.
// Atur parameter ketiga ke true untuk menyertakan data yang sudah ada.
CreateIndexRequest request = new CreateIndexRequest("<TABLE_NAME>", indexMeta, false);
client.createIndex(request);
}
Buat indeks sekunder lokal
Kode contoh berikut membuat indeks sekunder lokal. Kolom kunci primer pertama indeks (PRIMARY_KEY_NAME_1) harus sesuai dengan kolom kunci primer pertama tabel data. Tipe indeks diatur ke IT_LOCAL_INDEX dan mode pembaruan ke IUM_SYNC_INDEX (pembaruan sinkron).
Atur IncludeBaseData ke true untuk menyertakan baris tabel data yang sudah ada ke dalam indeks. Waktu yang diperlukan untuk mengisi ulang data yang sudah ada bervariasi tergantung pada volume data.
private static void createIndex(SyncClient client) {
IndexMeta indexMeta = new IndexMeta("<INDEX_NAME>");
// Kolom kunci primer pertama indeks sekunder lokal harus sesuai
// dengan kolom kunci primer pertama tabel data.
indexMeta.addPrimaryKeyColumn(PRIMARY_KEY_NAME_1);
indexMeta.addPrimaryKeyColumn(DEFINED_COL_NAME_1);
indexMeta.addDefinedColumn(DEFINED_COL_NAME_2);
indexMeta.setIndexType(IT_LOCAL_INDEX);
indexMeta.setIndexUpdateMode(IUM_SYNC_INDEX);
// Buat indeks tanpa mengisi ulang data yang sudah ada.
// Atur parameter ketiga ke true untuk menyertakan data yang sudah ada.
CreateIndexRequest request = new CreateIndexRequest("<TABLE_NAME>", indexMeta, false);
client.createIndex(request);
}
Langkah 3: Baca data dari tabel indeks
Jalur pembacaan bergantung pada kolom atribut yang Anda perlukan:
Kolom ada di tabel indeks — baca langsung dari tabel indeks.
Kolom tidak ada di tabel indeks — lakukan pemindaian pada tabel indeks untuk mendapatkan kunci primer setiap baris yang cocok, lalu ambil kolom tersebut dari tabel data. Pendekatan dua langkah ini menimbulkan biaya baca tambahan per baris, sehingga sertakan kolom atribut yang sering dikueri ke dalam indeks saat membuatnya.
Contoh berikut menggunakan Tablestore SDK for Java. SDK berikut juga didukung: Go, Python, Node.js, .NET, dan PHP.
Baca satu baris
Buat kunci primer tabel indeks dan panggil getRow. Kode contoh berikut membaca satu baris, lalu membaca kembali dengan filter kolom tertentu.
private static void getRowFromIndex(SyncClient client) {
// Buat kunci primer tabel indeks.
// Untuk indeks sekunder lokal, kolom kunci primer pertama harus sesuai
// dengan kolom kunci primer pertama tabel data.
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();
// Mengembalikan null jika baris tidak ada.
System.out.println("Hasil baca: " + row);
// Baca kolom tertentu.
criteria.addColumnsToGet("Col0");
getRowResponse = client.getRow(new GetRowRequest(criteria));
row = getRowResponse.getRow();
System.out.println("Hasil baca: " + row);
}
Baca rentang baris
Tentukan kunci primer awal dan akhir pada tabel indeks, lalu panggil getRange dalam loop hingga nextStartPrimaryKey bernilai null.
Gunakan indeks sekunder global
Jika semua kolom yang diperlukan ada di tabel indeks, baca langsung dari indeks.
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("Hasil pemindaian tabel indeks:");
while (true) {
GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
for (Row row : getRangeResponse.getRows()) {
System.out.println(row);
}
if (getRangeResponse.getNextStartPrimaryKey() != null) {
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
} else {
break;
}
}
}
Jika kolom yang diperlukan tidak ada di tabel indeks, lakukan pemindaian pada indeks untuk mendapatkan kunci primer setiap baris yang cocok, lalu ambil kolom tersebut dari tabel data.
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()) {
// Ekstrak kunci primer tabel data dari baris indeks.
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();
// Ambil kolom yang diperlukan dari tabel data.
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("<TABLE_NAME>", mainTablePK);
criteria.addColumnsToGet(DEFINED_COL_NAME_3);
criteria.setMaxVersions(1);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row mainTableRow = getRowResponse.getRow();
System.out.println(row);
}
if (getRangeResponse.getNextStartPrimaryKey() != null) {
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
} else {
break;
}
}
}
Gunakan indeks sekunder lokal
Jika semua kolom yang diperlukan ada di tabel indeks, baca langsung dari indeks.
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("Hasil pemindaian tabel indeks:");
while (true) {
GetRangeResponse getRangeResponse = client.getRange(new GetRangeRequest(rangeRowQueryCriteria));
for (Row row : getRangeResponse.getRows()) {
System.out.println(row);
}
if (getRangeResponse.getNextStartPrimaryKey() != null) {
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
} else {
break;
}
}
}
Jika kolom yang diperlukan tidak ada di tabel indeks, lakukan pemindaian pada indeks untuk mendapatkan kunci primer setiap baris yang cocok, lalu ambil kolom tersebut dari tabel data.
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()) {
// Ekstrak kunci primer tabel data dari baris indeks.
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();
// Ambil kolom yang diperlukan dari tabel data.
SingleRowQueryCriteria criteria = new SingleRowQueryCriteria("TABLE_NAME", mainTablePK);
criteria.addColumnsToGet(DEFINED_COL_NAME3);
criteria.setMaxVersions(1);
GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
Row mainTableRow = getRowResponse.getRow();
System.out.println(row);
}
if (getRangeResponse.getNextStartPrimaryKey() != null) {
rangeRowQueryCriteria.setInclusiveStartPrimaryKey(getRangeResponse.getNextStartPrimaryKey());
} else {
break;
}
}
}
Lampiran: Hapus tabel indeks
Hapus tabel indeks jika tidak lagi diperlukan.
Contoh berikut menggunakan Tablestore SDK for Java. SDK lain yang juga didukung meliputi: Go, Python, Node.js, .NET, dan PHP.
private static void deleteIndex(SyncClient client) {
DeleteIndexRequest request = new DeleteIndexRequest("<TABLE_NAME>", "<INDEX_NAME>");
client.deleteIndex(request);
}
FAQ
Referensi
Gunakan indeks sekunder melalui Konsol Tablestore atau CLI Tablestore. Untuk informasi selengkapnya, lihat Gunakan indeks sekunder di Konsol Tablestore dan Indeks sekunder.
Untuk opsi kueri yang lebih fleksibel—seperti pencarian teks lengkap, kueri Boolean, kueri awalan, dan kueri fuzzy—gunakan fitur indeks pencarian. Untuk informasi selengkapnya, lihat Ikhtisar.