DynamoDB: interroger tous les éléments similaires d'un certain type
En gardant à l'esprit les meilleures pratiques d'avoir une table unique et de répartir uniformément les éléments sur les partitions en utilisant des clés de partition aussi uniques que possible dans DynamoDB, je suis coincé à un problème.
Supposons que ma table stocke des éléments tels que users, itemset devices. Je stocke l'identifiant de chacun de ces éléments comme clé de partition. Chaque identifiant est précédé de son type tel que user-XXXX, item-XXXX& device-XXXX.
Maintenant, le problème est de savoir comment puis-je interroger uniquement un certain type d'objet? Par exemple, je veux tout récupérer users, comment faire? Cela aurait été possible si l' begin_withopérateur avait été autorisé pour les clés de partition afin que je puisse rechercher le préfixe mais les clés de partition n'autorisent que l' opérateur d' égalité .
Si maintenant j'utilise mes types comme clés de partition, par exemple, usercomme clé de partition, puis user-idcomme clé de tri, cela fonctionnerait mais cela n'entraînerait que quelques clés de partition et donc entraînerait le problème des touches de raccourci. Et créer plusieurs tables est une mauvaise pratique.
Toutes les suggestions sont les bienvenues.
Réponses
c'est une excellente question. Je suis également intéressé de savoir ce que font les autres pour résoudre ce problème.
Si vous stockez vos données avec une clé de partition de <type>-<id>, vous prenez en charge le modèle d'accès "récupérer un élément par ID". Vous avez correctement noté que vous ne pouvez pas utiliser begins_withsur une clé de partition, vous laissant sans moyen clair d'obtenir une collection d'éléments de ce type.
Je pense que vous êtes sur la bonne voie avec la création d' une partition de la clé <type>(par exemple Users, Devicesetc.) avec une sorte de sens clé. Cependant, comme vos éléments ne sont pas répartis uniformément sur la table, vous êtes confronté à la possibilité d'une partition chaude.
Une façon de résoudre le problème d'une partition chaude est d'utiliser un cache externe, ce qui empêcherait votre base de données d'être atteinte à chaque fois. Cela vient avec une complexité supplémentaire que vous ne voudrez peut-être pas introduire dans votre application, mais c'est une option.
Vous avez également la possibilité de distribuer les données entre les partitions dans DynamoDB, en implémentant efficacement votre propre cache. Par exemple, disons que vous avez une application Web qui a une liste des «10 meilleurs appareils» directement sur la page d'accueil. Vous pouvez créer des partitions DEVICES#1, DEVICES#2, DEVICES#3, ..., DEVICES#Nque chaque stocke le top 10 appareils. Lorsque votre application a besoin de récupérer les 10 principaux appareils, elle peut sélectionner au hasard l'une de ces partitions pour obtenir les données. Cela peut ne pas fonctionner pour une partition aussi grande que Users, mais c'est un modèle assez soigné à considérer.
Pour étendre cette idée, vous pouvez partitionner les périphériques par une autre métrique significative (par exemple <manufactured_date>ou <created_at>). Cela permettrait de répartir plus uniformément vos Deviceéléments dans la base de données. Votre application serait chargée d'interroger toutes les partitions et de fusionner les résultats, mais vous réduiriez / élimineriez le problème de partition chaude. La documentation AWS DynamoDB aborde ce modèle de manière plus approfondie.
Il n'y a guère d'approche unique pour la modélisation des données DynamoDB, ce qui peut rendre la modélisation des données extrêmement délicate! Vos modèles d'accès spécifiques détermineront la solution la mieux adaptée à votre scénario.
Garder à l'esprit les meilleures pratiques d'avoir une seule table et de répartir uniformément les éléments sur les partitions
Soulignant rapidement les deux choses mentionnées ici.
- Une distribution absolument uniforme des clés de partition est une bonne pratique.
- Avoir les enregistrements dans une seule table, dans un sens générique, c'est éviter d'avoir à normaliser comme dans une base de données relationnelle. En d'autres termes, il est bon de construire avec des informations dupliquées / redondantes. Ce n'est donc pas nécessairement une notion de regrouper toutes les données possibles dans une seule table.
Maintenant, le problème est de savoir comment puis-je interroger uniquement un certain type d'objet? Par exemple, je veux récupérer tous les utilisateurs, comment faire?
Imaginons que vous ayez cette table avec uniquement des données "utilisateur". Cela permettrait-il de récupérer tous les utilisateurs? Bien sûr que non, à moins qu'il n'y ait une seule partition avec le type appelé user et le reste dit derrière une clé de tri de userid.
Et créer plusieurs tables est une mauvaise pratique
Je ne pense pas que ce soit considéré comme mauvais d'avoir plus d'une table. C'est mauvais si nous stockons comme des tables normalisées et que nous devons utiliser JOIN pour rassembler les données.
Cela dit, quelle serait la meilleure approche à suivre.
- La différence fondamentale est de penser d'abord aux requêtes à dériver lors de la conception de la table. Cela suggérera même si DynamoDB est le bon choix. Par exemple, l'exigence de sélectionner chaque utilisateur peut être un mauvais cas d'utilisation pour DynamoDB à résoudre.
- Les modèles de requête suggéreront en outre quelle est la meilleure clé de partition en main. Le choix de DynamoDB ici est-il dû à une ingestion élevée et à des écritures principalement immuables?
- Ai-je toujours la clé de partition en main pour effectuer la sélection que je dois effectuer?
- À quoi ressembleraient les instructions de mise à jour, aura-t-il à nouveau la clé de partition pour effectuer les mises à jour?
- Dois-je filtrer davantage par colonnes supplémentaires et cela peut-il être l'ordre de tri par défaut?
Lorsque vous commencez à répondre à certaines de ces questions, un meilleur modèle peut apparaître.