147 votes

Interrogation de DynamoDB par date

Je viens d'une base de données relationnelle et j'essaie de travailler avec DynamoDB d'Amazon.

J'ai une table avec une clé de hachage "DataID" et une plage "CreatedAt" et un tas d'éléments dedans.

J'essaie d'obtenir tous les éléments qui ont été créés après une date spécifique et triés par date, ce qui est assez simple dans une base de données relationnelle.

Dans DynamoDB, la chose la plus proche que j'ai pu trouver est une requête et l'utilisation du filtre range key greater than. Le seul problème est que pour effectuer une requête, j'ai besoin d'une clé de hachage, ce qui va à l'encontre du but recherché.

Alors qu'est-ce que je fais mal ? Le schéma de ma table est-il mauvais ? La clé de hachage ne devrait-elle pas être unique ? Ou existe-t-il une autre façon d'effectuer une requête ?

83voto

Warren Parad Points 985

Compte tenu de la structure actuelle de votre table, cela n'est pas possible actuellement dans DynamoDB. L'énorme défi est de comprendre que la clé de hachage de la table (partition) doit être traitée comme la création de tables distinctes. D'une certaine manière, c'est vraiment puissant (pensez aux clés de partition comme à la création d'une nouvelle table pour chaque utilisateur ou client, etc...).

Les requêtes ne peuvent être effectuées que dans une seule partition. C'est vraiment la fin de l'histoire. Cela signifie que si vous voulez effectuer une requête par date (vous voudrez utiliser les msec depuis l'époque), tous les éléments que vous voulez récupérer dans une seule requête doivent avoir le même Hash (clé de partition).

Je dois préciser ceci. Vous pouvez absolument scan par le critère que vous recherchez, ce n'est pas un problème, mais cela signifie que vous allez examiner chaque ligne de votre tableau, et ensuite vérifier si cette ligne a une date qui correspond à vos paramètres. C'est très coûteux, surtout si votre activité consiste à stocker des événements par date en premier lieu (c'est-à-dire si vous avez beaucoup de lignes).

Vous pouvez être tenté de mettre toutes les données dans une seule partition pour résoudre le problème, et vous le pouvez tout à fait, mais votre débit sera douloureusement bas, étant donné que chaque partition ne reçoit qu'une fraction de la quantité totale fixée.

La meilleure chose à faire est de déterminer des partitions plus utiles à créer pour sauvegarder les données :

  • Avez-vous vraiment besoin de regarder toutes les lignes, ou seulement les lignes d'un utilisateur spécifique ?

  • Serait-il possible de réduire la liste par mois et de faire plusieurs requêtes (une pour chaque mois) ? Ou par année ?

  • Si vous faites de l'analyse de séries temporelles, il y a quelques options, changez la clé de partition en quelque chose de calculé sur PUT pour faire le query plus facile, ou utiliser un autre produit aws comme kinesis qui se prête à la journalisation des appendices seulement.

47voto

Mike Brant Points 39322

Réponse actualisée :

DynamoDB permet de spécifier des index secondaires pour faciliter ce type de requête. Les index secondaires peuvent être soit globaux, ce qui signifie que l'index couvre l'ensemble de la table à travers les clés de hachage, soit locaux, ce qui signifie que l'index existerait dans chaque partition de clé de hachage, nécessitant ainsi que la clé de hachage soit également spécifiée lors de la requête.

Pour le cas d'utilisation de cette question, vous voudriez utiliser un index secondaire global sur le champ "CreatedAt".

Pour en savoir plus sur les index secondaires de DynamoDB voir la documentation sur l'index secondaire

Réponse originale :

DynamoDB n'autorise pas les recherches indexées sur la clé d'intervalle uniquement. La clé de hachage est nécessaire pour que le service sache dans quelle partition chercher les données.

Vous pouvez bien sûr effectuer une opération de balayage pour filtrer par la valeur de la date, mais cela nécessiterait un balayage complet de la table, ce qui n'est pas idéal.

Si vous avez besoin d'effectuer une recherche indexée d'enregistrements par heure sur plusieurs clés primaires, DynamoDB n'est peut-être pas le service idéal à utiliser, ou vous devrez peut-être utiliser une table séparée (soit dans DynamoDB, soit dans un magasin relationnel) pour stocker les métadonnées des éléments sur lesquels vous pouvez effectuer une recherche indexée.

29voto

Gireesh Points 567

L'approche que j'ai suivie pour résoudre ce problème est de créer un index secondaire global comme ci-dessous. Je ne suis pas sûr que ce soit la meilleure approche, mais j'espère qu'elle sera utile à quelqu'un.

Hash Key                 | Range Key
------------------------------------
Date value of CreatedAt  | CreatedAt

Limitation imposée à l'utilisateur de l'API HTTP pour spécifier le nombre de jours pour récupérer les données, par défaut 24 heures.

De cette façon, je peux toujours spécifier le HashKey comme le jour de la date actuelle et le RangeKey peut utiliser les opérateurs > et < lors de la récupération. De cette façon, les données sont également réparties sur plusieurs tiroirs.

4voto

greg Points 1968

Vous pourriez faire en sorte que la clé de hachage ressemble à un identifiant de "catégorie de produit", puis que la clé de plage soit une combinaison d'un horodatage et d'un identifiant unique ajouté à la fin. De cette façon, vous connaissez la clé de hachage et vous pouvez toujours interroger la date avec un supérieur à.

1voto

DGolberg Points 248

Vous pouvez avoir plusieurs clés de hachage identiques ; mais seulement si vous avez une clé de gamme qui varie. Pensez-y comme aux formats de fichiers : vous pouvez avoir deux fichiers portant le même nom dans le même dossier tant que leur format est différent. Si leur format est le même, leur nom doit être différent. Le même concept s'applique aux clés de hachage/plage de DynamoDB ; il suffit de considérer le hachage comme le nom et la plage comme le format.

De plus, je ne me souviens pas s'ils existaient à l'époque de l'OP (je ne crois pas que ce soit le cas), mais ils proposent désormais des index secondaires locaux.

Si j'ai bien compris, cela devrait vous permettre d'exécuter les requêtes souhaitées sans avoir à effectuer un balayage complet. L'inconvénient est que ces index doivent être spécifiés lors de la création de la table, et aussi (je crois) ne peuvent pas être vides lors de la création d'un élément. En outre, ils nécessitent un débit supplémentaire (bien que généralement moins important qu'un scan) et du stockage, ce n'est donc pas une solution parfaite, mais une alternative viable, pour certains.

Je continue cependant à recommander la réponse de Mike Brant comme la méthode préférée d'utilisation de DynamoDB, et j'utilise moi-même cette méthode. Dans mon cas, j'ai juste une table centrale avec seulement une clé de hachage comme mon ID, puis des tables secondaires qui ont un hachage et une plage qui peuvent être interrogés, puis l'élément pointe le code vers "l'élément d'intérêt" de la table centrale, directement.

Des données supplémentaires concernant les index secondaires peuvent être trouvées dans la documentation DynamoDB d'Amazon. aquí pour les personnes intéressées.

Quoi qu'il en soit, j'espère que cela aidera toute autre personne qui tombera sur ce fil.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X