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'essaye 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 je puisse trouver est une requête et l'utilisation de la clé de plage supérieure à filtre. Le seul problème est que pour effectuer une requête, j'ai besoin d'une clé de hachage qui va à l'encontre de l'objectif.
Alors qu'est-ce que je fais de mal? Mon schéma de table est-il incorrect, la clé de hachage ne devrait-elle pas être unique? ou y a-t-il une autre façon d'interroger?
la source
CreatedAt
plus d'un certain point.Compte tenu de la structure de votre table actuelle, cela n'est actuellement pas possible dans DynamoDB. Le défi majeur est de comprendre que la clé de hachage de la table (partition) doit être traitée comme la création de tables séparées. À certains égards, 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 souhaitez interroger par date (vous voudrez utiliser msec depuis l'époque), tous les éléments que vous souhaitez récupérer dans une seule requête doivent avoir le même Hash (clé de partition).
Je devrais nuancer cela. Vous pouvez absolument
scan
en fonction du critère que vous recherchez, ce n'est pas un problème, mais cela signifie que vous examinerez chaque ligne de votre tableau, puis vérifierez si cette ligne a une date qui correspond à vos paramètres. C'est vraiment cher, surtout si vous êtes dans le domaine du stockage d'événements par date en premier lieu (c'est-à-dire que 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 absolument, mais votre débit sera douloureusement bas, étant donné que chaque partition ne reçoit qu'une fraction du montant total défini.
La meilleure chose à faire est de déterminer les partitions les plus utiles à créer pour enregistrer les données:
Avez-vous vraiment besoin de regarder toutes les lignes ou s'agit-il uniquement des lignes d'un utilisateur spécifique?
Serait-il correct de commencer par affiner la liste par mois et de faire plusieurs requêtes (une pour chaque mois)? Ou par année?
Si vous effectuez une analyse de séries chronologiques, il y a quelques options, changez la clé de partition en quelque chose de calculé
PUT
pour rendre lequery
plus facile, ou utilisez un autre produit aws comme kinesis qui se prête à la journalisation par ajout uniquement.la source
yyyy
et hash à ce sujet, mais créez également unecreated
date que vous pouvez utiliser comme clé de plage. Ensuite, vous obtenez 10 Go de données par an (27 Mo par jour), ce qui convient probablement à plus de circonstances. Cela signifie que vous devez créer une requête par an lorsque les requêtes de date dépassent la limite de l'année, mais au moins cela fonctionnera et c'est plus sûr que de créer une clé de hachage factice.L'approche que j'ai suivie pour résoudre ce problème consiste à créer un index secondaire global comme ci-dessous. Je ne sais pas si c'est la meilleure approche mais, espérons-le, si elle est utile à quelqu'un.
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 sur 24 heures.
De cette façon, je peux toujours spécifier le HashKey comme jour de la date actuelle et 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 fragments.
la source
Votre clé de hachage (principale de sorte) doit être unique (sauf si vous avez une plage comme indiqué par d'autres).
Dans votre cas, pour interroger votre table, vous devez avoir un index secondaire.
Votre clé de hachage est ID Votre index secondaire est défini comme: DataID-Created-index (c'est le nom que DynamoDB utilisera)
Ensuite, vous pouvez faire une requête comme celle-ci:
Essentiellement, votre requête ressemble à:
L'index secondaire augmentera les unités de capacité de lecture / écriture requises, vous devez donc en tenir compte. C'est toujours bien mieux que de faire un scan, qui sera coûteux en lecture et en temps (et est limité à 100 éléments je crois).
Ce n'est peut-être pas la meilleure façon de le faire, mais pour quelqu'un qui a l'habitude de RD (je suis également habitué à SQL), c'est le moyen le plus rapide d'être productif. Comme il n'y a aucune contrainte en ce qui concerne le schéma, vous pouvez créer quelque chose qui fonctionne et une fois que vous avez la bande passante pour travailler de la manière la plus efficace, vous pouvez changer les choses.
la source
Vous pouvez faire de la clé Hash quelque chose comme un identifiant de `` catégorie de produit '', puis la clé de plage comme une combinaison d'un horodatage avec un identifiant unique ajouté à la fin. De cette façon, vous connaissez la clé de hachage et pouvez toujours interroger la date avec une valeur supérieure à.
la source
Vous pouvez avoir plusieurs clés de hachage identiques; mais seulement si vous avez une clé de plage qui varie. Pensez-y comme des formats de fichiers; vous pouvez avoir 2 fichiers avec 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; pensez simplement au hachage comme nom et à la plage comme format.
De plus, je ne me souviens pas s'ils en avaient au moment de l'OP (je ne crois pas qu'ils l'avaient fait), mais ils offrent maintenant des index secondaires locaux.
Je crois comprendre que cela devrait maintenant vous permettre d'effectuer les requêtes souhaitées sans avoir à effectuer une analyse complète. L'inconvénient est que ces index doivent être spécifiés lors de la création de la table et que (je crois) ne peuvent pas être vides lors de la création d'un élément. De plus, ils nécessitent un débit supplémentaire (bien que généralement pas autant qu'une analyse) et du stockage, ce n'est donc pas une solution parfaite, mais une alternative viable, pour certains.
Je recommande quand même la réponse de Mike Brant comme méthode préférée d'utilisation de DynamoDB; et utiliser cette méthode moi-même. Dans mon cas, j'ai juste une table centrale avec seulement une clé de hachage comme identifiant, puis des tables secondaires qui ont un hachage et une plage qui peuvent être interrogées, 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 ici pour les personnes intéressées.
Quoi qu'il en soit, j'espère que cela aidera quiconque se produira sur ce fil.
la source
Réponse mise à jour Il n'existe aucun moyen pratique de le faire à l'aide de requêtes Dynamo DB avec un débit prévisible. Une option (sous-optimale) consiste à utiliser un GSI avec un HashKey artificiel et CreatedAt. Puis interrogez par HashKey seul et mentionnez ScanIndexForward pour classer les résultats. Si vous pouvez trouver une HashKey naturelle (dites la catégorie de l'article, etc.), cette méthode est gagnante. D'autre part, si vous conservez la même HashKey pour tous les éléments, cela affectera le débit principalement lorsque votre ensemble de données dépasse 10 Go (une partition)
Réponse originale: Vous pouvez le faire maintenant dans DynamoDB en utilisant GSI. Faites le champ «CreatedAt» comme un GSI et émettez des requêtes comme (GT some_date). Stockez la date sous forme de nombre (msec depuis l'époque) pour ce type de requêtes.
Les détails sont disponibles ici: Global Secondary Indexes - Amazon DynamoDB: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html#GSI.Using
C'est une fonctionnalité très puissante. Sachez que la requête est limitée à (EQ | LE | LT | GE | GT | BEGINS_WITH | BETWEEN) Condition - Amazon DynamoDB: http://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Condition.html
la source
CreatedAt
devrait être la clé de plage du GSI, vous devrez choisir une clé de hachage - et vous revenez là où vous avez commencé, car vous ne pourrez interroger GTCreatedAt
que sur une valeur spécifique du touche dièse.