Différence entre les index locaux et globaux dans DynamoDB

Je suis curieux de connaître ces deux index secondaires et leurs différences. Il est difficile d’imaginer à quoi cela ressemble. Et je pense que cela aidera plus de gens que moi.

Les index secondaires locaux dépendent toujours de la clé de hachage d’origine. Lorsque vous fournissez une table avec une plage de hachage +, pensez au LSI sous forme de hachage + plage1, hachage + plage2 .. hachage + plage6. Vous obtenez 5 autres atsortingbuts de plage à interroger. De plus, il n’y a qu’un seul débit provisionné.

Les index secondaires globaux définissent un nouveau paradigme – différentes clés de hachage / plage par index.
Cela rompt l’utilisation d’origine d’une clé de hachage par table. C’est également pour cette raison que lors de la définition de GSI, vous devez append un débit provisionné par index et le payer.

Des informations plus détaillées sur les différences peuvent être trouvées dans l’ annonce de GSI

Voici la définition formelle de la documentation:

Index secondaire global – un index avec une clé de hachage et de plage qui peut être différente de celle de la table. Un index secondaire global est considéré comme “global” car les requêtes sur l’index peuvent couvrir toutes les données d’une table, sur toutes les partitions.

Index secondaire local – Index ayant la même clé de hachage que la table, mais une clé de plage différente. Un index secondaire local est “local” en ce sens que chaque partition d’un index secondaire local est étendue à une partition de table qui possède la même clé de hachage.

Cependant, les différences vont bien au-delà des possibilités en termes de définitions clés. Trouvez ci-dessous certains facteurs importants qui auront un impact direct sur le coût et les efforts pour maintenir les index:

  • Débit :

Les index secondaires locaux consumnt le débit de la table. Lorsque vous interrogez des enregistrements via l’index local, l’opération consum des unités de capacité de lecture de la table. Lorsque vous effectuez une opération d’écriture (créer, mettre à jour, supprimer) dans une table comportant un index local, il y aura deux opérations d’écriture, l’une pour la table et l’autre pour l’index. Les deux opérations consumnt des unités de capacité d’écriture de la table.

Les index secondaires globaux ont leur propre débit alloué, lorsque vous interrogez l’index, l’opération consum de la capacité de lecture de l’index, lorsque vous effectuez une opération d’écriture (créer, mettre à jour, supprimer) dans une table avec un index global opérations d’écriture, une pour la table une autre pour l’index *.

* Lorsque vous définissez le débit provisionné pour l’indice secondaire global, veillez à respecter les exigences suivantes:

Pour qu’une écriture de table réussisse, les parameters de débit provisionnés pour la table et tous ses index secondaires globaux doivent avoir une capacité d’écriture suffisante pour prendre en charge l’écriture; sinon, l’écriture sur la table sera limitée.

  • La gestion :

Les index secondaires locaux ne peuvent être créés que lors de la création de la table. Il est impossible d’append l’index secondaire local à une table existante. Une fois l’index créé, vous ne pouvez pas le supprimer.

Les index secondaires globaux peuvent être créés lorsque vous créez la table et que vous l’ajoutez à une table existante. La suppression d’un index secondaire global existant est également autorisée.

  • Consistance de lecture:

Les index secondaires locaux prennent en charge la cohérence finale ou forte, tandis que l’indice secondaire global ne prend en charge que la cohérence éventuelle.

  • Projection:

Les index secondaires locaux permettent de récupérer des atsortingbuts qui ne sont pas projetés sur l’index (bien qu’avec des coûts supplémentaires: performances et unités de capacité consommées). Avec l’index secondaire global, vous ne pouvez récupérer que les atsortingbuts projetés dans l’index.

Considération particulière concernant le caractère unique des clés définies pour les index secondaires:

Dans un index secondaire local, la valeur de la clé de plage NE DOIT PAS être unique pour une valeur de clé de hachage donnée, la même chose s’applique aux index secondaires globaux, les valeurs de clé (hachage et plage) ne doivent PAS être uniques.

Source: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html

Voici les recherches possibles par index:

  • Par hachage
  • Par Hash + Range
  • Par hachage + index local
  • Par index global
  • Par indice global + indice de plage

Index de hachage et de plage d’une table: il s’agit des index habituels des versions précédentes du kit Amazon AWS SDK.

Index globaux et locaux: il s’agit d’index «supplémentaires» créés sur une table, en plus des index de hachage et de plage existants de la table. L’indice global est similaire à un hachage. L’indice d’intervalle se comporte de la même manière que l’index d’intervalle utilisé avec le hachage de la table. Dans votre modèle d’entité dans votre code, le getter doit être annoté de la manière suivante:

  • Pour les index globaux:

    @DynamoDBIndexHashKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS) @DynamoDBAtsortingbute(atsortingbuteName = PROPERTY_USER) public Ssortingng getUser() { return user; } 
  • Pour l’index d’intervalle associé à l’index global:

     @DynamoDBIndexRangeKey(globalSecondaryIndexName = INDEX_GLOBAL_RANGE_US_TS) @DynamoDBAtsortingbute(atsortingbuteName = PROPERTY_TIMESTAMP) public Ssortingng getTimestamp() { return timestamp; } 

De plus, si vous lisez une table par un index global, il doit s’agir d’une lecture éventuelle (non cohérente):

 queryExpression.setConsistentRead(false); 

Une façon de le dire est la suivante:

LSI – vous permet d’effectuer une requête sur une seule clé de hachage tout en utilisant plusieurs atsortingbuts différents pour “filtrer” ou restreindre la requête.

GSI – vous permet d’effectuer des requêtes sur plusieurs clés de hachage dans un tableau, mais cela entraîne un coût supplémentaire.

Une ventilation plus détaillée des types de tables et de leur fonctionnement, ci-dessous:

Hash Only

Comme vous le savez probablement déjà; une clé de hachage en elle-même doit être unique car l’écriture sur une clé de hachage qui existe déjà remplace les données existantes.

Hash + Range

Une clé de hachage + une clé de plage vous permet d’avoir plusieurs clés de hachage identiques, à condition qu’elles aient une clé de plage différente. Dans ce cas, si vous écrivez dans une clé de hachage qui existe déjà, mais que vous utilisez une clé de plage qui n’est pas déjà utilisée par cette clé de hachage, cela en fait un nouvel élément, alors que si un élément possède la même combinaison existe déjà, il écrase l’élément correspondant.

Une autre façon de penser à cela est comme un fichier avec un format. Vous pouvez avoir un fichier avec le même nom (hachage) qu’un autre, dans le même dossier (tableau), tant que leur format (plage) est différent. De même, vous pouvez avoir plusieurs fichiers du même format tant que leur nom est différent.

LSI

Un LSI est fondamentalement identique à un Hash-Key + Range-Key et suit les mêmes règles que lors de la création d’éléments, sauf que vous devez également fournir des valeurs pour les LSI; ils ne peuvent pas être laissés vides / null.

Dire qu’un LSI est “Range-Key 2” n’est pas tout à fait correct car vous ne pouvez pas avoir (en utilisant l’analogie avec les fichiers et les formats précédents) un fichier nommé file.format.lsi et file.format.lsi2 . Vous pouvez cependant avoir file.format.lsi et file.format2.lsi ou file.format.lsi et file2.format.lsi .

Fondamentalement, un LSI est juste une “clé de filtre”, pas une clé de plage réelle; votre combinaison de valeurs de hachage et de plage de base doit toujours être unique alors que les valeurs LSI ne doivent pas être uniques du tout. Un moyen plus simple de le regarder peut être de considérer le LSI comme des données dans les fichiers. Vous pouvez écrire du code qui trouve tous les fichiers avec le nom “PROJECT101”, quel que soit leur fileFormat , puis lit les données à l’intérieur pour déterminer ce qui doit être inclus dans la requête et ce qui est omis. C’est essentiellement ainsi que fonctionne LSI (sans la charge supplémentaire d’ouvrir le fichier pour en lire le contenu).

GSI

Pour GSI, vous créez essentiellement une autre table pour chaque GSI, mais sans avoir à gérer plusieurs tables distinctes qui reflètent les données entre elles; c’est pourquoi ils coûtent plus de débit.

Ainsi, pour un GSI, vous pouvez spécifier fileName comme clé de hachage de base et fileFormat comme fileFormat de plage de base. Vous pouvez ensuite spécifier un GSI ayant une clé de hachage de fileName2 et une clé de fileFormat2 de fileFormat2 . Vous pouvez ensuite interroger soit fileName soit fileName2 si vous le souhaitez, contrairement à LSI où vous pouvez uniquement interroger fileName .

Les principaux avantages sont que vous ne devez conserver qu’une seule table au lieu de 2, et chaque fois que vous écrivez sur le hachage / plage principal ou sur le hachage / la plage GSI, l’autre sera automatiquement mise à jour, vous ne pouvez donc pas “oublier” de mettre à jour les autres tables comme vous le pouvez avec une configuration multi-tables. De plus, il n’y a aucune chance de perte de connexion après la mise à jour de l’une et avant la mise à jour de l’autre, comme c’est le cas avec la configuration multi-tables.

De plus, un GSI peut “chevaucher” la combinaison base / hachage. Donc, si vous voulez créer une table avec fileFormat et fileFormat comme base de Hash / Range et filePriority et filePriority comme votre GSI, vous pouvez.

Enfin, une combinaison GSI Hash + Range ne doit pas nécessairement être unique, alors que la combinaison Hash + Range de base doit être unique. C’est quelque chose qui n’est pas possible avec une configuration double / multi-tables, mais c’est avec GSI. En conséquence, vous DEVEZ fournir des valeurs à la fois pour la base et GSI Hash + Range, lors de la mise à jour; aucune de ces valeurs ne peut être vide / nulle.

Une autre façon d’expliquer: LSI vous aide à faire des requêtes supplémentaires sur les éléments avec la même clé de hachage. GSI vous aide à faire les requêtes similaires sur les éléments “à travers la table”. Donc très utile.

Si vous avez une table de profil utilisateur: unique-id, nom, email. Ici, si vous avez besoin de rendre le tableau interrogeable sur le nom, l’email, alors la seule façon est de le rendre GSI (LSI ne vous aidera pas)

Cette documentaion donne de bonnes explications:

https://aws.amazon.com/blogs/aws/now-available-global-secondary-indexes-for-amazon-dynamodb/

Je ne pouvais pas commenter cette question, mais ce qui est mieux en termes de performance d’écriture et de lecture:

(Index local avec débit de lecture et d’écriture de table de 100) ou (Index global avec un débit de lecture / écriture de 50 avec un débit de lecture / écriture de 50?)

Je n’ai pas besoin de clé de partition séparée pour mon cas d’utilisation, donc l’index local devrait être suffisant pour les fonctionnalités requirejses.