Un index secondaire étend les capacités d'interrogation par clé primaire d'une table de données à d'autres colonnes. Pour interroger des données via des colonnes d'attribut, créez un index secondaire afin d'accélérer les requêtes. Après avoir spécifié des colonnes prédéfinies, utilisez-les comme colonnes d'index ou colonnes d'attribut de la table d'index lors de la création de l'index secondaire. Une fois l'index secondaire créé, servez-vous-en pour interroger les données.
Prérequis
Une table de données doit exister. Le nombre maximal de versions (max versions) de cette table doit être égal à 1 et sa durée de vie (TTL) doit satisfaire à l'une des conditions suivantes :
La TTL de la table de données est définie sur -1 (les données n'expirent jamais).
Si la TTL de la table de données n'est pas égale à -1, la table doit interdire les mises à jour (l'option Allow Updates est définie sur No).
La TTL d'un index secondaire est identique à celle de la table de données.
Étape 1 : (Facultatif) Gérer les colonnes prédéfinies
Lors de l'utilisation d'un index secondaire, si aucune colonne prédéfinie n'est configurée ou si les colonnes existantes ne répondent pas à vos besoins, ajoutez ou supprimez des colonnes prédéfinies pour la table de données.
Gérez les colonnes prédéfinies à l'aide du SDK Tablestore pour Java ou du SDK Tablestore pour Go. Cette section utilise le SDK Java comme exemple.
Ajouter une colonne prédéfinie
Paramètres
|
Parameter |
Type |
Description |
|
tableName (required) |
String |
Le nom de la table de données. |
|
definedColumns (required) |
List |
Les informations relatives à la colonne prédéfinie. Chaque colonne prédéfinie contient les paramètres suivants :
|
Exemple de code
L'exemple suivant ajoute une colonne prédéfinie nommée name de type STRING à la table de données example_table.
AddDefinedColumnRequest request = new AddDefinedColumnRequest();
request.setTableName("example_table");
request.addDefinedColumn("name", DefinedColumnType.STRING);
client.addDefinedColumn(request);
Supprimer une colonne prédéfinie
Paramètres
|
Parameter |
Type |
Description |
|
tableName (required) |
String |
Le nom de la table de données. |
|
definedColumns (required) |
List<String> |
Les noms des colonnes prédéfinies à supprimer. |
Exemple de code
L'exemple suivant supprime la colonne prédéfinie nommée name de la table de données example_table.
DeleteDefinedColumnRequest request = new DeleteDefinedColumnRequest();
request.setTableName("example_table");
request.addDefinedColumn("name");
client.deleteDefinedColumn(request);
Étape 2 : Créer un index secondaire
Appelez l'opération CreateIndex pour créer une table d'index associée à une table de données existante et accélérer ainsi les requêtes. Les index secondaires se divisent en index globaux et locaux. Créez un index global ou local selon vos besoins métier.
Vous pouvez également créer une ou plusieurs tables d'index simultanément avec la table de données en appelant l'opération CreateTable. Pour plus d'informations, consultez la rubrique Créer une table de données.
Les exemples ci-dessous utilisent le SDK Tablestore pour Java. Les SDK suivants sont également pris en charge : Go, Python, Node.js, .NET et PHP.
Créer un index secondaire global
L'exemple suivant crée un index secondaire global nommé example_global_index pour la table de données example_table. La table d'index contient les données existantes.
Définissez IncludeBaseData sur true pour inclure les lignes existantes de la table de données dans l'index. Le temps nécessaire au remplissage des données existantes varie selon le volume de données.
IndexMeta indexMeta = new IndexMeta("example_global_index");
indexMeta.addPrimaryKeyColumn("category");
indexMeta.addDefinedColumn("status");
CreateIndexRequest request =
new CreateIndexRequest("example_table", indexMeta, true);
client.createIndex(request);
Créer un index secondaire local
Pour créer un index secondaire local, utilisez la première colonne de clé primaire de la table de données comme première colonne de clé primaire de l'index. Définissez respectivement le type d'index et le mode de mise à jour sur IT_LOCAL_INDEX et IUM_SYNC_INDEX.
Définissez IncludeBaseData sur true pour inclure les lignes existantes de la table de données dans l'index. Le temps nécessaire au remplissage des données existantes varie selon le volume de données.
IndexMeta indexMeta = new IndexMeta("example_local_index");
indexMeta.addPrimaryKeyColumn("user_id");
indexMeta.addPrimaryKeyColumn("category");
indexMeta.addDefinedColumn("status");
indexMeta.setIndexType(IndexType.IT_LOCAL_INDEX);
indexMeta.setIndexUpdateMode(IndexUpdateMode.IUM_SYNC_INDEX);
CreateIndexRequest request =
new CreateIndexRequest("example_table", indexMeta, true);
client.createIndex(request);
Étape 3 : Lire les données depuis la table d'index
Lisez une seule ligne ou une plage de données à partir d'une table d'index. La méthode de lecture dépend de la présence des colonnes d'attribut à renvoyer dans la table d'index :
Les colonnes d'attribut se trouvent dans la table d'index : lisez directement la table d'index pour obtenir les données.
Les colonnes d'attribut ne se trouvent pas dans la table d'index : interrogez la table de données pour récupérer les données.
Les exemples ci-dessous utilisent le SDK Tablestore pour Java. Les SDK suivants sont également pris en charge : Go, Python, Node.js, .NET et PHP.
Lire une seule ligne
Lisez une seule ligne de données. L'exemple suivant lit une ligne unique à partir de l'index secondaire global example_global_index en fonction de la clé primaire complète et renvoie uniquement la colonne d'attribut status.
PrimaryKey primaryKey = PrimaryKeyBuilder.createPrimaryKeyBuilder()
.addPrimaryKeyColumn("category", PrimaryKeyValue.fromString("books"))
.addPrimaryKeyColumn("user_id", PrimaryKeyValue.fromString("user-1"))
.addPrimaryKeyColumn("order_id", PrimaryKeyValue.fromLong(101L))
.build();
SingleRowQueryCriteria criteria =
new SingleRowQueryCriteria("example_global_index", primaryKey);
criteria.addColumnsToGet("status");
criteria.setMaxVersions(1);
GetRowResponse response = client.getRow(new GetRowRequest(criteria));
System.out.println(response.getRow());
Lire une plage de lignes
Lisez les données comprises dans une plage de clés primaires spécifiée. Définissez les clés primaires de début et de fin sur la table d'index, puis appelez getRange en boucle jusqu'à ce que nextStartPrimaryKey soit null.
Utiliser un index secondaire global
Si les colonnes d'attribut à renvoyer se trouvent dans la table d'index, lisez directement la table d'index pour obtenir les données.
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("Scan result of the index table:");
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;
}
}
}
Si les colonnes d'attribut à renvoyer ne se trouvent pas dans la table d'index, interrogez la table de données pour récupérer les données.
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()) {
// Extract the data table primary key from the index row.
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();
// Fetch the required columns from the data table.
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;
}
}
}
Utiliser un index secondaire local
Si les colonnes d'attribut à renvoyer se trouvent dans la table d'index, lisez directement la table d'index pour obtenir les données.
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("Scan result of the index table:");
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;
}
}
}
Si les colonnes d'attribut à renvoyer ne se trouvent pas dans la table d'index, interrogez la table de données pour récupérer les données.
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()) {
// Extract the data table primary key from the index row.
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();
// Fetch the required columns from the data table.
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;
}
}
}
Annexe : Supprimer une table d'index
Supprimez une table d'index lorsqu'elle n'est plus nécessaire.
Les exemples ci-dessous utilisent le SDK Tablestore pour Java. Les SDK suivants sont également pris en charge : Go, Python, Node.js, .NET et PHP.
L'exemple suivant supprime l'index secondaire example_index de la table de données example_table.
DeleteIndexRequest request =
new DeleteIndexRequest("example_table", "example_index");
DeleteIndexResponse response = client.deleteIndex(request);
System.out.println(response.getRequestId());
FAQ
Références
Utilisez également les index secondaires via la console ou l'outil de ligne de commande. Pour plus d'informations, consultez les rubriques Utiliser des index secondaires dans la console et Utiliser des index secondaires à l'aide de la CLI.
Pour des méthodes d'accélération des requêtes plus flexibles et variées, telles que les requêtes combinées multi-critères, la recherche en texte intégral, les requêtes par préfixe et les requêtes floues, utilisez des index de recherche. Pour plus d'informations, consultez la rubrique Présentation des index de recherche.