

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Modélisation des données pour les tables DynamoDB
<a name="data-modeling"></a>

Avant de nous plonger dans la modélisation de données, il est important de comprendre certains principes fondamentaux de DynamoDB. DynamoDB est une base de données NoSQL de type clé-valeur, ce qui procure un certaine flexibilité dans les schémas. L’ensemble des attributs de données, hormis les attributs de clé de chaque élément, peut être uniforme ou discret. Le schéma de clé DynamoDB se présente soit sous la forme d’une clé primaire simple constituée d’une clé de partition qui identifie de manière unique un élément, soit sous la forme d’une clé primaire composite constituée d’une clé de partition et d’une clé de tri qui définissent de manière unique un élément. La clé de partition est hachée pour déterminer l’emplacement physique des données et les récupérer. Il est donc important de choisir un attribut qui possède une cardinalité élevée et une capacité de mise à l’échelle horizontale en guise de clé de partition pour assurer une distribution uniforme des données. Si l’attribut de clé de tri est facultatif dans le schéma de clé, le fait de disposer d’une clé de tri permet de modéliser des relations de type « un-à-plusieurs » et de créer des collections d’éléments dans DynamoDB. Les clés de tri sont également appelées clés de plage. Celles-ci permettent de trier les éléments d’une collection d’éléments et offrent également une certaine flexibilité dans les opérations basées sur une plage.

Pour en savoir plus sur le schéma de clé DynamoDB et les bonnes pratiques associées, vous pouvez consulter les pages suivantes :
+ [Partitions et distribution des données dans DynamoDB](HowItWorks.Partitions.md) 
+ [Bonnes pratiques pour la conception et l’utilisation performantes de clés de partition dans DynamoDB](bp-partition-key-design.md) 
+ [Bonnes pratiques concernant l’utilisation de clés de tri pour organiser les données dans DynamoDB](bp-sort-keys.md) 
+ [Choix de la clé de partition DynamoDB appropriée](https://aws.amazon.com/blogs/database/choosing-the-right-dynamodb-partition-key/) 

Il est souvent nécessaire d’utiliser des index secondaires pour prendre en charge d’autres modèles de requête dans DynamoDB. Les index secondaires sont des tables alternatives (ou « shadow ») dans lesquelles les mêmes données sont organisées via un schéma de clé différent de celui de la table de base. Dans un index secondaire local (LSI), la clé de partition est la même que celle de la table de base, ce qui permet d’avoir une autre clé de tri et ainsi de partager la capacité de la table de base. Un index secondaire global (GSI) peut avoir une clé de partition et un attribut de clé de tri différents de ceux de la table de base, ce qui signifie que la gestion du débit dans le cas d’un GSI est indépendante de la table de base.

Pour en savoir plus sur les index secondaires et les bonnes pratiques, vous pouvez consulter les pages suivantes :
+ [Amélioration de l’accès aux données avec les index secondaires dans DynamoDB](SecondaryIndexes.md) 
+ [Bonnes pratiques d’utilisation d’index secondaires dans DynamoDB](bp-indexes.md) 

À présent, intéressons-nous d’un peu plus près à la modélisation de données. Le processus de conception d’un schéma flexible et hautement optimisé sur DynamoDB, ou sur n’importe quelle base de données NoSQL d’ailleurs, peut être une compétence difficile à acquérir. Ce module a pour objectif de vous aider à développer un diagramme mental pour concevoir un schéma qui vous fera passer du cas d’utilisation à la production. Nous commencerons par une introduction au choix fondamental d’un modèle, en comparant la conception à une seule table et la conception à plusieurs tables. Nous passerons ensuite en revue les différents modèles de conception (composantes de base) qui peuvent être utilisés pour obtenir divers résultats organisationnels ou de performance pour votre application. Enfin, nous verrons les packages complets de conception de schémas que nous fournissons pour différents cas d’utilisation et secteurs d’activité.

![\[Image qui illustre la relation conceptuelle entre les données, les composantes juste en dessous, puis la base qui se trouve sous les composantes.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesign.png)


**Topics**
+ [Collections d'éléments : comment modéliser one-to-many les relations dans DynamoDB](WorkingWithItemCollections.md)
+ [Principes de base de la modélisation des données dans DynamoDB](data-modeling-foundations.md)
+ [Composantes de base de la modélisation des données dans DynamoDB](data-modeling-blocks.md)
+ [Packages de conception de schémas de modélisation de données dans DynamoDB](data-modeling-schemas.md)
+ [Bonnes pratiques de modélisation des données relationnelles dans DynamoDB](bp-relational-modeling.md)

# Collections d'éléments : comment modéliser one-to-many les relations dans DynamoDB
<a name="WorkingWithItemCollections"></a>

Dans DynamoDB, une *collection d'éléments* est un groupe d'éléments ayant la même valeur de clé de partition, ce qui signifie que les éléments sont liés. Les collections d'éléments constituent le principal mécanisme de modélisation one-to-many des relations dans DynamoDB. Les collections d'articles peuvent uniquement exister sur des tables ou des index configurés pour utiliser une [clé primaire composite](HowItWorks.CoreComponents.md#HowItWorks.CoreComponents.PrimaryKey).

**Note**  
Les collections d'éléments peuvent exister dans une table de base ou un index secondaire. Pour plus d'informations sur la façon dont les collections d'articles interagissent avec les index, voir [Collections d’articles dans les index secondaires locaux](LSI.md#LSI.ItemCollections).

Considérez le tableau suivant montrant trois utilisateurs différents et leurs inventaires en jeu :

![\[Trois collections d'articles différentes avec des attributs différents.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/item_collection.png)


Pour certains éléments de chaque collection, la clé de tri est une concaténation composée d'informations utilisées pour regrouper des données, telles que `inventory::armor`, `inventory::weapon` ou `info`. Chaque collection d'articles peut comporter une combinaison différente de ces attributs comme clé de tri. L'utilisateur `account1234` est doté d'un élément `inventory::weapons`, mais ce n'est pas le cas de l'utilisateur `account1387` (parce qu'il n'en a pas encore trouvé). L'utilisateur `account1138` n'utilise que deux éléments pour sa clé de tri (puisqu'il n'a pas encore d'inventaire), tandis que les autres utilisateurs en utilisent trois.

DynamoDB vous permet de récupérer sélectivement des éléments de ces collections d'articles pour effectuer les opérations suivantes :
+ Récupérer tous les éléments d'un utilisateur particulier
+ Récupérer un seul élément d'un utilisateur particulier
+ Récupérer tous les éléments d'un type spécifique appartenant à un utilisateur particulier

## Accélérer les requêtes en organisant vos données avec des collections d'articles
<a name="WorkingWithItemCollections.Example"></a>

Dans cet exemple, chacun des éléments de ces trois collections d'objets représente un joueur et le modèle de données que nous avons choisi, en fonction des modèles d'accès du jeu et du joueur. De quelles données le jeu a-t-il besoin ? Quand en a-t-il besoin ? À quelle fréquence en a-t-il besoin ? Quel est le coût de ce procédé ? Ces décisions de modélisation des données ont été prises en fonction des réponses à ces questions.

Dans ce jeu, il y a une page différente présentée au joueur pour son inventaire des armes et une autre page pour les armures. Lorsque le joueur ouvre son inventaire, les armes sont affichées en premier car nous voulons que cette page se charge extrêmement rapidement, tandis que les pages d'inventaire suivantes peuvent être chargées par la suite. Étant donné que chacun de ces types d'objets peut être assez volumineux lorsque le joueur acquiert d'autres objets dans le jeu, nous avons décidé que chaque page d'inventaire serait son propre objet dans la collection d'objets du joueur dans la base de données. 

La section suivante explique comment interagir avec les collections d'articles via l'opération `Query`.

**Topics**
+ [Accélérer les requêtes en organisant vos données avec des collections d'articles](#WorkingWithItemCollections.Example)

# Principes de base de la modélisation des données dans DynamoDB
<a name="data-modeling-foundations"></a>

Cette section s’intéresse à la couche de base en examinant les deux types de conception de table : à une seule table ou à plusieurs tables.

![\[Image qui illustre la relation conceptuelle entre les données, les composantes juste en dessous, puis la base qui se trouve sous les composantes. L’accent est mis sur la base.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesignFoundation.png)


## Principe de base de la conception à une seule table
<a name="data-modeling-foundations-single"></a>

Notre premier choix pour la base de notre schéma DynamoDB se porte sur la **conception à une seule table**. La conception à une seule table est un modèle qui vous permet de stocker plusieurs types (entités) de données dans une seule table DynamoDB. Elle vise à optimiser les modèles d’accès aux données, à améliorer les performances et à réduire les coûts en évitant de gérer plusieurs tables et les relations complexes entre elles. Cela est possible, car DynamoDB stocke les éléments dotés de la même clé de partition (appelée collection d’éléments) sur les mêmes partitions les uns que les autres. Dans cette conception, différents types de données sont stockés sous forme d’éléments dans la même table et chaque élément est identifié par une clé de tri unique.

![\[Image montrant une table et la façon dont la clé de tri est utilisée pour différencier chaque élément par type d’entité au sein de la même collection d’éléments UserID.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SingleTableSchema.png)


**Avantages**
+ Localité des données pour prendre en charge les requêtes relatives à plusieurs types d’entités lors d’un seul appel de base de données
+ Réduit les coûts financiers globaux et les coûts de latence liés aux lectures :
  + Une seule requête pour deux éléments d’un volume total inférieur à 4 ko équivaut à 0,5 RCU finalement cohérente
  + Deux requêtes pour deux éléments d’un volume total inférieur à 4 ko équivalent à 1 RCU finalement cohérente (0,5 RCU chacune)
  + La durée nécessaire pour renvoyer deux appels de base de données distincts sera en moyenne supérieure à celle d’un seul appel
+ Réduit le nombre de tables à gérer :
  + Il n’est pas nécessaire de conserver les autorisations entre plusieurs rôles ou politiques IAM 
  + La gestion de la capacité de la table est calculée en moyenne pour toutes les entités, ce qui se traduit généralement par un modèle de consommation plus prévisible
  + La surveillance nécessite moins d’alarmes
  + Les clés de chiffrement gérées par le client ne doivent subir une rotation que sur une table
+ Facilite le trafic vers la table :
  + En agrégeant plusieurs modèles d’utilisation dans la même table, l’utilisation globale a tendance à être plus fluide (de la même manière que la performance d’un indice boursier a tendance à être plus fluide que celle d’une action individuelle), ce qui fonctionne mieux pour obtenir une utilisation plus élevée avec les tables en mode provisionné

**Inconvénients**
+ La courbe d’apprentissage peut être ardue en raison d’une conception paradoxale par rapport aux bases de données relationnelles
+ Les exigences en matière de données doivent être cohérentes pour tous les types d’entités
  + Pour les sauvegardes, c’est tout ou rien. Par conséquent, si certaines données ne sont pas essentielles à votre mission, pensez à les conserver dans une table séparée
  + Le chiffrement des tables est partagé entre tous les éléments. Pour les applications multilocataires avec des exigences de chiffrement de locataire individuel, un chiffrement côté client est requis
  + Les tables contenant à la fois des données historiques et des données opérationnelles ne tireront pas autant d’avantages de l’activation de la classe de stockage Accès peu fréquent. Pour de plus amples informations, consultez [Classes de tables DynamoDB](HowItWorks.TableClasses.md). 
+ Toutes les données modifiées seront transmises à DynamoDB Streams, même si seul un sous-ensemble d’entités doit être traité.
  + Grâce aux filtres d’événements Lambda, cela n’affectera pas votre facture lorsque vous utiliserez Lambda, mais cela représentera un coût supplémentaire lorsque vous utiliserez Kinesis Consumer Library 
+ Lors de l’utilisation de GraphQL, la conception à une seule table sera plus difficile à mettre en œuvre.
+ Lorsque vous utilisez des clients SDK de niveau supérieur tels que [`DynamoDBMapper`](DynamoDBMapper.md) de Java ou le [client amélioré](DynamoDBEnhanced.md), le traitement des résultats peut s’avérer plus difficile, car les éléments d’une même réponse peuvent être associés à différentes classes

**Quand l’utiliser**

La conception à une seule table est indiquée pour les applications qui interrogent fréquemment plusieurs types d’entités ensemble ou qui ont besoin de maintenir des relations entre différents types de données. Elle est particulièrement efficace lorsque vos modèles d’accès tirent parti de la localisation des données et lorsque vous souhaitez minimiser les frais liés à la gestion de plusieurs tables.

## Principe de base de la conception à plusieurs tables
<a name="data-modeling-foundations-multi"></a>

Notre second choix pour la base de notre schéma DynamoDB se porte sur la conception à plusieurs tables****. La conception à plusieurs tables est un modèle qui ressemble davantage à une conception de base de données traditionnelle dans laquelle vous stockez un seul type (entité) de données dans chaque table DynamoDB. Les données de chaque table seront toujours organisées par clé de partition, de sorte que les performances au sein d’un même type d’entité seront optimisées en termes de capacité de mise à l’échelle et de performance, mais les requêtes sur plusieurs tables devront être effectuées indépendamment.

![\[Image montrant une table de forum contenant une liste de forums et quelques données agrégées.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/MultipleTable1.png)


![\[Image montrant une table de fil de discussion contenant une liste de fils de discussion partitionnés selon le forum spécifique auquel ils appartiennent.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/MultipleTable2.png)


**Avantages**
+ Plus simple à concevoir pour qui n’a pas l’habitude d’utiliser la conception à une seule table. 
+ Mise en œuvre simplifiée des résolveurs GraphQL grâce au mappage de chaque résolveur à une seule entité (table)
+ Permet de répondre à des exigences de données uniques pour différents types d’entités :
  + Possibilité d’effectuer des sauvegardes pour les tables individuelles qui sont essentielles à la mission 
  + Le chiffrement des tables peut être géré pour chaque table. Pour les applications multilocataires ayant des exigences de chiffrement de locataire individuel, les tables de locataire distinctes permettent à chaque client d’avoir sa propre clé de chiffrement
  + La classe de stockage Accès peu fréquent peut être activée uniquement sur les tables contenant des données historiques afin de tirer pleinement parti des économies sur les coûts. Pour de plus amples informations, consultez [Classes de tables DynamoDB](HowItWorks.TableClasses.md).
+ Chaque table disposera de son propre flux de données de modification, ce qui permettra de concevoir une fonction Lambda dédiée pour chaque type d’élément plutôt qu’un seul processeur monolithique.

**Inconvénients**
+ Pour les modèles d'accès qui nécessitent des données sur plusieurs tables, plusieurs lectures depuis DynamoDB seront nécessaires et les données devront peut-être processed/joined figurer sur le code client.
+ Les opérations et la surveillance de plusieurs tables nécessitent davantage d' CloudWatch alarmes et chaque table doit être mise à l'échelle de manière indépendante
+ Les autorisations de chaque table devront être gérées séparément. L’ajout de tables à l’avenir exigera de modifier tous les rôles ou politiques IAM nécessaires.

**Quand l’utiliser**

Si les modèles d’accès de votre application n’ont pas besoin d’interroger simultanément plusieurs entités ou tables, la conception à plusieurs tables est une approche appropriée et suffisante.

# Composantes de base de la modélisation des données dans DynamoDB
<a name="data-modeling-blocks"></a>

Cette section s’intéresse à la couche des composants principaux en vous présentant des modèles de conception que vous pouvez utiliser dans votre application.

![\[Image qui illustre la relation conceptuelle entre les données, les composantes juste en dessous, puis la base qui se trouve sous les composantes. L’accent est mis sur la base.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesignBlocks.png)


**Topics**
+ [Composante de base Clé de tri composite](#data-modeling-blocks-composite)
+ [Composante de base Multilocataire](#data-modeling-blocks-multi-tenancy)
+ [Composante de base Index fragmenté](#data-modeling-blocks-sparse-index)
+ [Composante de base Durée de vie](#data-modeling-blocks-ttl)
+ [Composante de base Durée de vie pour l’archivage](#data-modeling-blocks-ttl-archival)
+ [Composante de base Partitionnement vertical](#data-modeling-blocks-vertical-partitioning)
+ [Composante de base Partitionnement d’écriture](#data-modeling-blocks-write-sharding)

## Composante de base Clé de tri composite
<a name="data-modeling-blocks-composite"></a>

Quand on pense à NoSQL, on peut également le considérer comme non relationnel. En fin de compte, il n’y a aucune raison pour que les relations ne puissent pas être placées dans un schéma DynamoDB. Elles ont simplement un aspect différent de celui des bases de données relationnelles et de leurs clés étrangères. L’un des modèles les plus importants que nous pouvons utiliser pour développer une hiérarchie logique de nos données dans DynamoDB est la clé de tri composite. Pour en concevoir une, il convient généralement de séparer chaque couche de la hiérarchie (couche parent > couche enfant > couche petit-enfant) par un hashtag. Par exemple, `PARENT#CHILD#GRANDCHILD#ETC`.

![\[Image montrant un élément dans une table, UserID étant la clé primaire et une combinaison d’autres attributs étant la clé de tri.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ShoppingCart.png)


Alors que dans DynamoDB, une clé de partition exige toujours la valeur exacte pour interroger les données, nous pouvons appliquer une condition partielle à la clé de tri de gauche à droite, comme pour traverser une arborescence binaire.

L’exemple ci-dessus s’applique à une boutique de e-commerce où le panier doit être conservé entre les sessions utilisateur. Chaque fois que l’utilisateur se connecte, il est possible qu’il souhaite voir l’intégralité de son panier, y compris les articles enregistrés pour plus tard. Mais lorsqu’il passe au paiement, seuls les articles du panier actif doivent être chargés pour l’achat. Étant donné que ces deux `KeyConditions` demandent explicitement les clés de tri CART, les données supplémentaires de la liste de souhaits sont simplement ignorées par DynamoDB au moment de la lecture. Bien que les articles enregistrés et actifs fassent partie du même panier, nous devons les traiter différemment selon les parties de l’application. L’application d’une expression `KeyCondition` au préfixe de la clé de tri est donc le moyen le plus optimisé de récupérer uniquement les données nécessaires pour chaque partie de l’application.

**Fonctionnalités principales de cette composante de base**
+ Les articles associés sont stockés localement les uns par rapport aux autres pour accéder efficacement aux données. 
+ À l'aide d'`KeyCondition`expressions, les sous-ensembles de la hiérarchie peuvent être récupérés de manière sélective, ce qui signifie qu'il n'y a aucun gaspillage RCUs 
+ Les différentes parties de l’application peuvent stocker leurs articles sous un préfixe spécifique pour éviter le remplacement des articles ou les conflits d’écriture.

## Composante de base Multilocataire
<a name="data-modeling-blocks-multi-tenancy"></a>

De nombreux clients utilisent DynamoDB pour héberger les données de leurs applications multilocataires. Pour ces scénarios, nous souhaitons concevoir le schéma de manière à conserver toutes les données d’un seul locataire dans sa propre partition logique de la table. On s’appuie sur le concept de collection d’éléments, qui désigne tous les éléments d’une table DynamoDB ayant la même clé de partition. Pour plus d’informations sur la manière dont DynamoDB aborde la multilocation, consultez [Multitenancy on DynamoDB](https://docs.aws.amazon.com/whitepapers/latest/multi-tenant-saas-storage-strategies/multitenancy-on-dynamodb.html). 

![\[Image montrant une table pouvant s’appliquer à un site d’hébergement de photos multilocataire. La clé primaire se compose comme suit : les utilisateurs correspondent à la clé de partition et les différentes photos à la clé de tri. L’attribut de chaque élément indique l’URL où la photo est hébergée.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/MultiTenant.png)


Cet exemple s’applique à un site d’hébergement de photos qui compte potentiellement des milliers d’utilisateurs. Dans un premier temps, chaque utilisateur charge uniquement des photos sur son propre profil, mais par défaut, nous n’autorisons pas un utilisateur à voir les photos d’un autre utilisateur. Dans l’idéal, un niveau d’isolation supplémentaire devrait être ajouté à l’autorisation d’appel de chaque utilisateur à votre API afin de garantir qu’il ne demande que des données issues de sa propre partition. Au niveau du schéma, les clés de partition uniques sont suffisantes.

**Fonctionnalités principales de cette composante de base**
+ La quantité de données lues par un utilisateur ou un locataire ne peut être qu’égale à la quantité totale d’éléments dans sa partition.
+ La suppression des données d’un locataire en raison de la fermeture de son compte ou d’une demande de conformité peut être effectuée avec tact et à moindre coût. Il suffit d’exécuter une requête où la clé de partition est égale à l’ID du locataire, puis d’exécuter une opération `DeleteItem` pour chaque clé primaire renvoyée.

**Note**  
Conçu dans un souci de mutualisation, vous pouvez utiliser différents fournisseurs de clés de chiffrement sur une même table pour isoler les données en toute sécurité. [AWS Database Encryption SDK](https://docs.aws.amazon.com/database-encryption-sdk/latest/devguide/what-is-database-encryption-sdk.html) pour Amazon DynamoDB vous permet d’inclure le chiffrement côté client dans vos charges de travail DynamoDB. Vous pouvez effectuer un chiffrement au niveau des attributs, ce qui vous permet de chiffrer des valeurs d’attributs spécifiques avant de les stocker dans votre table DynamoDB et de rechercher des attributs chiffrés sans déchiffrer l’intégralité de la base de données au préalable. 

## Composante de base Index fragmenté
<a name="data-modeling-blocks-sparse-index"></a>

Parfois, un modèle d’accès exige de rechercher des éléments qui correspondent à un élément rare ou à un élément qui reçoit un statut (ce qui nécessite une réponse ayant fait l’objet d’une remontée). Plutôt que d’effectuer régulièrement des recherches sur l’ensemble du jeu de données pour ces éléments, nous pouvons tirer parti du fait que peu de données sont chargées dans les **index secondaires globaux (GSI)**. Cela signifie que seuls les éléments de la table de base, dont les attributs sont définis dans l’index, seront répliqués dans l’index.

![\[Image montrant une table de base qui reçoit une grande quantité de données à l’état stable\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SparseBaseTable.png)


![\[Image montrant un index secondaire global qui reçoit uniquement les éléments qui ont fait l’objet d’une remontée\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SparseGSI.png)


Cet exemple illustre un cas d’utilisation IOT où chaque appareil sur le terrain communique régulièrement un état. Pour la plupart des signalements, on s’attend à ce que l’appareil indique que tout va bien, mais il peut arriver qu’il y ait un problème et qu’il faille le faire remonter à un réparateur. Pour les signalements nécessitant une remontée, l’attribut `EscalatedTo` est ajouté à l’élément, mais il n’est pas présent dans le cas contraire. Dans cet exemple, le GSI est partitionné par `EscalatedTo` et étant donné qu’il apporte les clés de la table de base, on peut voir quel DeviceID a signalé le problème et à quel moment.

Bien que les lectures soient moins coûteuses que les écritures dans DynamoDB, les index fragmentés constituent un outil très puissant pour les cas d’utilisation où les instances d’un type spécifique d’élément sont rares, mais où les lectures pour les trouver sont courantes.

**Fonctionnalités principales de cette composante de base**
+ Les coûts d'écriture et de stockage pour le GSI fragmenté ne s'appliquent qu'aux éléments qui correspondent au modèle clé, de sorte que le coût du GSI peut être nettement inférieur à GSIs celui d'autres modèles où tous les éléments sont répliqués 
+ Une clé de tri composite peut toujours être utilisée pour affiner davantage les éléments qui correspondent à la requête souhaitée. Par exemple, un horodatage peut être utilisé pour la clé de tri afin d’afficher uniquement les problèmes signalés au cours des X dernières minutes (`SK > 5 minutes ago, ScanIndexForward: False`).

## Composante de base Durée de vie
<a name="data-modeling-blocks-ttl"></a>

La plupart des données ont une certaine durée pendant laquelle on peut considérer qu’il vaut la peine de les conserver dans un entrepôt de données principal. Pour faciliter le vieillissement des données issues de DynamoDB, il existe une fonctionnalité appelée **Durée de vie (TTL)**. La fonctionnalité [TTL](TTL.md) vous permet de définir un attribut spécifique au niveau de la table qui surveille les éléments dotés d’un horodatage époque (dans le passé). Cela vous permet de supprimer gratuitement les enregistrements expirés de la table.

**Note**  
Si vous utilisez la [version 2019.11.21 (actuelle) des tables globales](GlobalTables.md) et que vous utilisez également la fonctionnalité [Durée de vie](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html), DynamoDB réplique les suppressions de TTL sur toutes les tables de réplica. La suppression de TTL initiale ne consomme pas de capacité d’écriture dans la région dans laquelle l’expiration de TTL a lieu. Toutefois, la suppression de TTL répliquée dans la ou les tables de réplicas consomme de la capacité d’écriture répliquée dans chacune des régions de réplica et des frais s’appliquent.

![\[Image montrant un tableau contenant les messages d’un utilisateur avec un attribut de durée de vie\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/TTL.png)


Cet exemple illustre une application conçue pour permettre à un utilisateur de créer des messages à durée de vie limitée. Lorsqu’un message est créé dans DynamoDB, l’attribut TTL est défini sur une date postérieure de sept jours par le code de l’application. Dans environ sept jours, DynamoDB constatera que l’horodatage epoch de ces éléments sera passé et les supprimera.

Les suppressions effectuées par TTL étant gratuites, il est fortement recommandé d’utiliser cette fonctionnalité pour supprimer les données historiques de la table. Cela réduira la facture mensuelle de stockage global et probablement les coûts de lecture des utilisateurs, car leurs requêtes nécessiteront de récupérer moins de données. Bien que la TTL soit activée au niveau de la table, c’est à vous de décider pour quels éléments ou entités vous souhaitez créer un attribut TTL et jusqu’à quelle date vous souhaitez définir l’horodatage epoch.

**Fonctionnalités principales de cette composante de base**
+ Les suppressions TTL sont exécutées en arrière-plan, sans incidence sur les performances de votre table. 
+ La TTL est un processus asynchrone qui s’exécute environ toutes les 6 heures, mais la suppression d’un enregistrement expiré peut prendre plus de 48 heures. 
  + Ne vous fiez pas aux suppressions TTL pour des cas d’utilisation tels que le verrouillage des enregistrements ou la gestion de l’état si des données obsolètes doivent être nettoyées en moins de 48 heures. 
+ Vous pouvez attribuer un nom valide à l’attribut TTL, mais la valeur doit être de type numérique.

## Composante de base Durée de vie pour l’archivage
<a name="data-modeling-blocks-ttl-archival"></a>

Bien que la TTL soit un outil efficace pour supprimer des données anciennes de DynamoDB, de nombreux cas d’utilisation exigent de conserver une archive des données pendant une période plus longue que celle de l’entrepôt de données principal. Dans ce cas, nous pouvons tirer parti de la suppression temporisée des enregistrements par TTL pour transférer les enregistrements expirés vers un entrepôt de données à long terme.

![\[Image montrant une table qui envoie une tâche de suppression par TTL aux flux DynamoDB, puis un entrepôt de données à long terme.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/TTLArchive.png)


Lorsqu’une suppression TTL est effectuée par DynamoDB, elle est tout de même transférée au flux DynamoDB en tant qu’événement `Delete`. Cependant, lorsque la TTL DynamoDB effectue la suppression, il existe un attribut sur l’enregistrement du flux de `principal:dynamodb`. En utilisant un abonné Lambda au DynamoDB Stream, nous pouvons appliquer un filtre d'événements uniquement pour l'attribut principal DynamoDB et savoir que tous les enregistrements correspondant à ce filtre doivent être transférés vers un magasin d'archives tel qu'Amazon Glacier.

**Fonctionnalités principales de cette composante de base**
+  Une fois que les lectures à faible latence de DynamoDB ne sont plus nécessaires pour les éléments historiques, leur migration vers un service de stockage plus froid tel qu'Amazon Glacier peut réduire les coûts de stockage de manière significative tout en répondant aux exigences de conformité des données de votre cas d'utilisation 
+ Si les données sont conservées dans Amazon S3, des outils d’analyse rentables tels qu’Amazon Athena ou Redshift Spectrum peuvent être utilisés pour effectuer une analyse historique des données.

## Composante de base Partitionnement vertical
<a name="data-modeling-blocks-vertical-partitioning"></a>

Les utilisateurs qui connaissent la base de données de modèles de documents seront familiers avec l’idée de stocker toutes les données associées dans un seul document JSON. DynamoDB prend en charge les types de données JSON, mais ne prend pas en charge l’exécution des `KeyConditions` sur les données JSON imbriquées. Puisque ce `KeyConditions` sont eux qui déterminent la quantité de données lues sur le disque et la consommation effective RCUs d'une requête, cela peut entraîner des inefficiences à grande échelle. Pour mieux optimiser les écritures et les lectures de DynamoDB, nous vous recommandons de diviser les entités individuelles du document en éléments DynamoDB individuels. Cette méthode s’appelle également le **partitionnement vertical**.

![\[Image montrant une grande structure de données formatée sous la forme d’un objet JSON imbriqué.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DocumentBlob.png)


![\[Image montrant une collection d’éléments dans laquelle la clé de tri de l’élément permet d’optimiser l’utilisation de DynamoDB.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SingleTableSchema.png)


Le partitionnement vertical, comme indiqué ci-dessus, est un exemple clé de conception à une seule table en action, mais il peut également être mis en œuvre sur plusieurs tables si vous le souhaitez. Étant donné que DynamoDB facture les écritures par incréments de 1 ko, vous devez idéalement partitionner le document de manière à obtenir des éléments inférieurs à 1 ko.

**Fonctionnalités principales de cette composante de base**
+ Une hiérarchie des relations entre les données est maintenue via des préfixes de clé de tri, de sorte que la structure unique du document puisse être reconstruite côté client si nécessaire. 
+ Des composants uniques de la structure de données peuvent être mis à jour indépendamment, de sorte que les mises à jour de petits éléments ne représentant qu’une seule WCU. 
+ À l’aide de la clé de tri `BeginsWith`, l’application peut récupérer des données similaires dans une seule requête, en agrégeant les coûts de lecture pour réduire le coût total/la latence.
+ Étant donné que les documents volumineux peuvent facilement dépasser la limite de 400 ko pour chaque élément dans DynamoDB, le partitionnement vertical permet de contourner cette limite.

## Composante de base Partitionnement d’écriture
<a name="data-modeling-blocks-write-sharding"></a>

L’une des rares limites strictes mises en place par DynamoDB est la limitation du débit qu’une seule partition physique peut maintenir par seconde (pas nécessairement une clé de partition unique). Ces limites sont actuellement les suivantes :
+ 1 000 WCU (ou 1 000 éléments écrits par seconde <= 1 ko) et 3 000 RCU (ou 3 000 lectures par seconde <=4 ko) *fortement cohérentes* ou 
+ 6 000 lectures par seconde <=4 ko *finalement cohérentes*

Si les demandes adressées à la table dépassent l’une de ces limites, une erreur est renvoyée au SDK client de `ThroughputExceededException`, ce que l’on appelle plus communément la limitation. Les cas d’utilisation exigeant des opérations de lecture au-delà de cette limite seront généralement mieux servis en plaçant un cache de lecture devant DynamoDB. Les opérations d’écriture, elles, exigent une conception au niveau du schéma connue sous le nom de **partitionnement d’écriture**.

![\[Image montrant comment DynamoDB partitionne les clés de partition sur plusieurs partitions afin d’éviter la limitation dus aux pics de trafic.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/WriteShardingProblem.png)


![\[Image montrant comment DynamoDB partitionne les clés de partition sur plusieurs partitions afin d’éviter la limitation dus aux pics de trafic.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/WriteShardingSolution.png)


Pour résoudre ce problème, nous allons ajouter un entier aléatoire à la fin de la clé de partition pour chaque concurrent dans le code `UpdateItem` de l’application. La plage du générateur d’entiers aléatoires devra avoir une limite supérieure égale ou supérieure au nombre attendu d’écritures par seconde pour un concurrent donné divisé par 1 000. Pour obtenir 20 000 votes par seconde, l’expression ressemblerait à rand(0,19). Maintenant que les données sont stockées sous des partitions logiques distinctes, elles doivent être recombinées au moment de la lecture. Comme le total des votes n’a pas besoin d’être en temps réel, une fonction Lambda programmée pour lire toutes les partitions de vote toutes les X minutes pourrait effectuer une agrégation occasionnelle pour chaque concurrent et la réécrire dans un enregistrement du total des votes unique pour les lectures en direct.

**Fonctionnalités principales de cette composante de base**
+ Pour les cas d’utilisation impliquant un débit d’écriture extrêmement élevé pour une clé de partition donnée qui ne peut être évité, les opérations d’écriture peuvent être réparties artificiellement sur plusieurs partitions DynamoDB. 
+ GSIs avec une faible cardinalité, une clé de partition devrait également utiliser ce modèle, car la régulation d'un GSI exercera une contre-pression sur les opérations d'écriture sur la table de base.

# Packages de conception de schémas de modélisation de données dans DynamoDB
<a name="data-modeling-schemas"></a>

Découvrez les packages de conception de schémas de modélisation des données pour DynamoDB, notamment les cas d’utilisation, les modèles d’accès et les conceptions de schéma finales pour les réseaux sociaux, les profils de jeu, la gestion des plaintes, les paiements récurrents, le statut des appareils et les boutiques en ligne.

![\[Image qui illustre la relation conceptuelle entre les données, les composantes juste en dessous, puis la base qui se trouve sous les composantes. L’accent est mis sur la base.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SchemaDesignData.png)


## Prérequis
<a name="data-modeling-prereqs"></a>

Avant d’essayer de concevoir notre schéma pour DynamoDB, nous devons d’abord recueillir certaines données prérequises concernant le cas d’utilisation que le schéma doit prendre en charge. Contrairement aux bases de données relationnelles, DynamoDB est partitionné par défaut, ce qui signifie que les données seront stockées sur plusieurs serveurs en arrière-plan. Il est donc important de concevoir en fonction de la localisation des données. Nous devrons établir la liste suivante pour chaque conception de schéma :
+ Liste des entités (diagramme ER)
+ Volumes et débit estimés pour chaque entité
+ Modèles d’accès qui doivent être pris en charge (requêtes et écritures)
+ Exigences en matière de conservation des données

**Topics**
+ [Prérequis](#data-modeling-prereqs)
+ [Conception de schéma de réseau social dans DynamoDB](data-modeling-schema-social-network.md)
+ [Conception de schéma de profil de jeu dans DynamoDB](data-modeling-schema-gaming-profile.md)
+ [Conception du schéma d’un système de gestion des réclamations dans DynamoDB](data-modeling-complaint-management.md)
+ [Conception d’un schéma de paiements récurrents dans DynamoDB](data-modeling-schema-recurring-payments.md)
+ [Surveillance des mises à jour du statut d’un appareil dans DynamoDB](data-modeling-device-status.md)
+ [Utilisation de DynamoDB comme magasin de données pour un magasin en ligne](data-modeling-online-shop.md)

# Conception de schéma de réseau social dans DynamoDB
<a name="data-modeling-schema-social-network"></a>

## Cas d’utilisation métier de réseau social
<a name="data-modeling-schema-social-network-use-case"></a>

Ce cas d’utilisation décrit l’utilisation de DynamoDB en tant que réseau social. Un réseau social est un service en ligne qui permet à différents utilisateurs d’interagir entre eux. Le réseau social que nous allons concevoir permettra à l’utilisateur de consulter une frise chronologique comprenant ses publications, ses abonnés, les personnes qu’il suit et les publications écrites par les personnes qu’il suit. Les modèles d’accès de cette conception de schéma sont les suivants :
+ Obtenir des informations utilisateur pour un ID utilisateur donné 
+ Obtenir la liste des abonnés pour un ID utilisateur donné
+ Obtenir la liste des personnes suivies pour un ID utilisateur donné
+ Obtenir la liste des publications pour un ID utilisateur donné
+ Obtenir la liste des utilisateurs qui aiment la publication pour un postID donné
+ Obtenir le nombre de « J’aime » pour un postID donné
+ Obtenir la chronologie pour un ID utilisateur donné

## Diagramme des relations entre entités du réseau social
<a name="data-modeling-schema-social-network-erd"></a>

Il s’agit du diagramme des relations entre entités (ERD) que nous utiliserons pour la conception du schéma de réseau social.

![\[ERD pour une application de réseau social qui affiche des entités telles que User, Post et Follower.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetworkERD.png)


## Modèles d’accès de réseau social
<a name="data-modeling-schema-social-network-access-patterns"></a>

Voici les modèles d’accès que nous allons prendre en considération pour la conception du schéma de réseau social.
+ `getUserInfoByUserID`
+ `getFollowerListByUserID`
+ `getFollowingListByUserID`
+ `getPostListByUserID`
+ `getUserLikesByPostID`
+ `getLikeCountByPostID`
+ `getTimelineByUserID`

## Évolution de la conception du schéma de réseau social
<a name="data-modeling-schema-social-network-design-evolution"></a>

DynamoDB étant une base de données NoSQL, elle ne vous permet pas d’effectuer une jointure, c’est-à-dire une opération qui combine des données provenant de plusieurs bases de données. Les clients qui ne connaissent pas DynamoDB peuvent appliquer les philosophies de conception du système de gestion de base de données relationnelle (SGBDR) (par exemple, créer une table pour chaque entité) à DynamoDB lorsqu’ils n’en ont pas besoin. La conception à une seule table de DynamoDB a pour objectif d’écrire des données pré-assemblées conformément au modèle d’accès de l’application, puis d’utiliser immédiatement les données sans aucun calcul supplémentaire. Pour plus d’informations, consultez [Single-table vs. multi-table design in DynamoDB](https://aws.amazon.com/blogs/database/single-table-vs-multi-table-design-in-amazon-dynamodb/). 

Voyons maintenant comment nous allons faire évoluer la conception de notre schéma pour prendre en compte tous les modèles d’accès.

**Étape 1 : Traitement du modèle d’accès 1 (`getUserInfoByUserID`)**

Pour obtenir les informations d’un utilisateur donné, nous allons devoir interroger ([https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Query.html)) la table de base avec la condition de clé `PK=<userID>`. L’opération de requête permet de paginer les résultats, ce qui peut être utile lorsqu’un utilisateur compte de nombreux followers. Pour plus d’informations sur Query, consultez [Interrogation de tables dans DynamoDB](Query.md). 

Dans notre exemple, nous suivons deux types de données pour notre utilisateur : count et info. Le type de données « count » d’un utilisateur reflète le nombre d’abonnés qu’il possède, le nombre d’utilisateurs qu’il suit et le nombre de publications qu’il a créées. Le type de données « info » d’un utilisateur reflètent ses informations personnelles telles que son nom.

Ces deux types de données sont représentés par les deux éléments ci-dessous. L’élément dont la clé de tri (SK) contient « count » est plus susceptible de changer que l’élément contenant « info ». DynamoDB prend en compte la taille de l’élément telle qu’elle apparaît avant et après la mise à jour et le débit provisionné consommé reflétera la plus grande de ces tailles d’élément. Même si vous mettez à jour simplement un sous-ensemble d’attributs de l’élément, [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) utilisera toujours la totalité du volume de débit provisionné (la plus grande des tailles d’élément « avant » et « après »). Vous pouvez obtenir les éléments en une seule opération `Query` et utiliser `UpdateItem` pour en ajouter ou en soustraire des attributs numériques existants.

![\[Résultat de l’opération de requête pour un utilisateur ayant l’ID u#12345 et ses données de nombre et d’informations.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork1.png)


**Étape 2 : Traitement du modèle d’accès 2 (`getFollowerListByUserID`)**

Pour obtenir la liste des utilisateurs qui suivent un utilisateur donné, nous devrons interroger (`Query`) la table de base avec la condition clé `PK=<userID>#follower`. 

![\[Résultat d’une opération de requête sur une table pour répertorier les abonnés de l’utilisateur ayant l’ID u#12345.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork2.png)


**Étape 3 : Traitement du modèle d’accès 3 (`getFollowingListByUserID`)**

Pour obtenir la liste des utilisateurs qu’un utilisateur donné suit, nous devrons interroger (`Query`) la table de base avec la condition clé `PK=<userID>#following`. Vous pouvez ensuite utiliser une opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html) pour regrouper plusieurs demandes et procéder comme suit :
+ Ajoutez l’utilisateur A à la liste d’abonnés de l’utilisateur B, puis augmentez le nombre d’abonnés de l’utilisateur B de 1.
+ Ajoutez l’utilisateur B à la liste d’abonnés de l’utilisateur A, puis augmentez le nombre d’abonnés de l’utilisateur A de 1.

![\[Résultat d’une opération de requête sur une table pour répertorier tous les utilisateurs ayant l’ID u#12345.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork3.png)


**Étape 4 : Traitement du modèle d’accès 4 (`getPostListByUserID`)**

Pour obtenir la liste des publications créées par un utilisateur donné, nous devrons interroger (`Query`) la table de base avec la condition clé `PK=<userID>#post`. Il est important de noter ici que la publication d'un utilisateur IDs doit être incrémentielle : la deuxième valeur PostID doit être supérieure à la première valeur PostID (car les utilisateurs veulent voir leurs publications de manière triée). Vous pouvez le faire en générant une publication IDs basée sur une valeur temporelle telle qu'un identifiant lexicographiquement triable universel (ULID).

![\[Résultat de l’opération de requête avec une condition clé pour obtenir une liste des articles créés par un utilisateur spécifique.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork4.png)


**Étape 5 : Traitement du modèle d’accès 5 (`getUserLikesByPostID`)**

Pour obtenir la liste des utilisateurs qui ont aimé la publication d’un utilisateur donné, nous devrons interroger (`Query`) la table de base avec la condition clé `PK=<postID>#likelist`. Cette approche est la même que celle que nous avons utilisée pour récupérer les listes d’abonnés et de personnes suivies dans le modèle d’accès 2 (`getFollowerListByUserID`) et le modèle d’accès 3 (`getFollowingListByUserID`).

![\[Résultat de l’opération de requête avec une condition clé pour obtenir une liste des utilisateurs qui ont aimé un article d’un utilisateur spécifique.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork5.png)


**Étape 6 : Traitement du modèle d’accès 6 (`getLikeCountByPostID`)**

Pour obtenir le nombre de « J’aime » pour une publication donnée, nous devons effectuer une opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) sur la table de base avec la condition clé `PK=<postID>#likecount`. Ce modèle d’accès peut entraîner des problèmes de limitation à chaque fois qu’un utilisateur ayant de nombreux abonnés (comme une célébrité, par exemple) crée une publication, car la limitation se produit lorsque le débit d’une partition dépasse 1 000 WCU par seconde. Ce problème n’est pas dû à DynamoDB, il apparaît simplement dans DynamoDB puisqu’il se trouve à la fin de la pile logicielle.

Vous devriez déterminer s’il est vraiment essentiel que tous les utilisateurs puissent consulter le nombre de « J’aime » simultanément ou si cela peut se faire progressivement au fil du temps. En général, le nombre de « J’aime » d’une publication n’a pas besoin d’être immédiatement précis à 100 %. Vous pouvez mettre en œuvre cette stratégie en plaçant une file d’attente entre votre application et DynamoDB pour que les mises à jour soient effectuées régulièrement.

![\[Résultat d'une GetItem opération avec une condition clé permettant d'obtenir le nombre de likes pour une publication spécifique.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork6.png)


**Étape 7 : Traitement du modèle d’accès 7 (`getTimelineByUserID`)**

Pour obtenir la chronologie d’un utilisateur donné, nous devons effectuer une opération `Query` sur la table de base avec la condition clé `PK=<userID>#timeline`. Imaginons un scénario dans lequel les abonnés d’un utilisateur doivent consulter leur publication de manière synchrone. Chaque fois qu’un utilisateur écrit une publication, sa liste d’abonnés est lue et ses userID et postID sont lentement saisis dans la clé de chronologie de tous ses abonnés. Ensuite, lorsque votre application démarre, vous pouvez lire la clé de chronologie avec l’opération `Query` et remplir l’écran de la chronologie avec une combinaison de userID et de postID en utilisant l’opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchGetItem.html) pour tout nouvel élément. Vous ne pouvez pas lire la chronologie à l’aide d’un appel d’API, mais cette solution est plus rentable si les publications peuvent être modifiées fréquemment.

La chronologie est un endroit qui affiche les publications récentes. Nous aurons donc besoin d’un moyen de nettoyer les anciennes. Au lieu d’utiliser une WCU pour les supprimer, vous pouvez utiliser la fonctionnalité [Durée de vie](TTL.md) de DynamoDB pour le faire gratuitement.

![\[Résultat de l’opération de requête avec une condition clé pour obtenir la chronologie d’un utilisateur donné affichant ses articles récents.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork7.png)


Tous les modèles d’accès et la façon dont ils sont traités par la conception du schéma sont résumés dans le tableau ci-dessous :


| Modèle d’accès | table/GSI/LSI de base | Opération | Valeur de la clé de partition | Valeur de clé de tri | Autres conditions/filtres | 
| --- | --- | --- | --- | --- | --- | 
| getUserInfoByUserID | Table de base | Query | PK=<userID> |  |  | 
| getFollowerListByUserID | Table de base | Query | PK=<userID>\$1follower |  |  | 
| getFollowingListByUserID | Table de base | Query | PK=<userID>\$1following |  |  | 
| getPostListByUserID | Table de base | Query | PK=<userID>\$1post |  |  | 
| getUserLikesByPostID | Table de base | Query | PK=<postID>\$1likelist |  |  | 
| getLikeCountByPostID | Table de base | GetItem | PK=<postID>\$1likecount |  |  | 
| getTimelineByUserID | Table de base | Query | PK=<userID>\$1timeline |  |  | 

## Schéma final du réseau social
<a name="data-modeling-schema-social-network-final-schema"></a>

Voici la conception du schéma final. Pour télécharger cette conception de schéma sous forme de fichier JSON, consultez les exemples [DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/SocialNetwork/SocialNetworkSchema.json) sur. GitHub

**Table de base :**

![\[Conception finale du schéma d'une table contenant les résultats de la requête et GetItem des opérations précédentes.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/SocialNetwork8.png)


## Utilisation de NoSQL Workbench avec cette conception de schéma
<a name="data-modeling-schema-social-network-nosql"></a>

Vous pouvez importer ce schéma final dans [NoSQL Workbench](workbench.md), un outil visuel qui fournit des fonctionnalités de modélisation des données, de visualisation des données et de développement des requêtes pour DynamoDB, afin d’explorer et de modifier davantage votre nouveau projet. Pour commencer, procédez comme suit :

1. Téléchargez NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Télécharger NoSQL Workbench pour DynamoDB](workbench.settingup.md).

1. Téléchargez le fichier de schéma JSON répertorié ci-dessus, qui est déjà au format du modèle NoSQL Workbench.

1. Importez le fichier de schéma JSON dans NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Importation d’un modèle de données existant](workbench.Modeler.ImportExisting.md). 

1. Une fois que vous l’avez importé dans NoSQL Workbench, vous pouvez modifier le modèle de données. Pour de plus amples informations, veuillez consulter [Modification d’un modèle de données existant](workbench.Modeler.Edit.md).

# Conception de schéma de profil de jeu dans DynamoDB
<a name="data-modeling-schema-gaming-profile"></a>

## Cas d’utilisation métier du profil de jeu
<a name="data-modeling-schema-gaming-profile-use-case"></a>

Ce cas d’utilisation décrit l’utilisation de DynamoDB pour stocker les profils des joueurs pour un système de jeu. Les utilisateurs (dans ce cas, les joueurs) doivent créer des profils avant de pouvoir interagir avec de nombreux jeux modernes, en particulier les jeux en ligne. Les profils de jeu incluent généralement les éléments suivants :
+ Informations de base telles que leur nom d’utilisateur
+ Données de jeu telles que les objets et l’équipement
+ Enregistrements de jeu tels que les tâches et les activités
+ Informations sociales telles que les listes d’amis

Pour satisfaire aux exigences précises en matière d’accès aux requêtes de données de cette application, les clés primaires (clé de partition et clé de tri) utiliseront des noms génériques (PK et SK) afin qu’elles puissent être surchargées de différents types de valeurs, comme nous le verrons ci-dessous.

Les modèles d’accès de cette conception de schéma sont les suivants :
+ Obtenir la liste d’amis d’un utilisateur
+ Obtenir toutes les informations d’un joueur
+ Obtenir la liste d’objets d’un utilisateur
+ Obtenir un objet spécifique de la liste d’objets de l’utilisateur
+ Mettre à jour le personnage d’un utilisateur
+ Mettre à jour le nombre d’objets d’un utilisateur

La taille du profil de jeu varie selon les jeux. La [compression des valeurs d’attributs volumineuses](bp-use-s3-too.md) permet de maintenir celles-ci dans les limites des éléments dans DynamoDB et de réduire les coûts. La stratégie de gestion du débit dépend de divers facteurs, tels que le nombre de joueurs, le nombre de parties jouées par seconde et la saisonnalité de la charge de travail. Généralement, pour un jeu récent, le nombre de joueurs et le niveau de popularité ne sont pas connus. Nous allons donc commencer par le [mode de débit à la demande](capacity-mode.md#capacity-mode-on-demand).

## Diagramme des relations entre entités de profil de jeu
<a name="data-modeling-schema-gaming-profile-erd"></a>

Il s’agit du diagramme des relations entre entités (ERD) que nous utiliserons pour la conception du schéma de profil de jeu.

![\[Diagramme des relations entre entités pour un profil de jeu, montrant les relations entre les entités, telles que User, Game et Score.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfileERD.png)


## Modèles d’accès de profil de jeu
<a name="data-modeling-schema-gaming-profile-access-patterns"></a>

Voici les modèles d’accès que nous allons prendre en considération pour la conception du schéma de réseau social.
+ `getPlayerFriends`
+ `getPlayerAllProfile`
+ `getPlayerAllItems`
+ `getPlayerSpecificItem`
+ `updateCharacterAttributes`
+ `updateItemCount`

## Évolution de la conception du schéma de profil de jeu
<a name="data-modeling-schema-social-network-design-evolution"></a>

À partir de l'ERD ci-dessus, nous pouvons voir qu'il s'agit d'un type de one-to-many relation de modélisation des données. Dans DynamoDB one-to-many, les modèles de données peuvent être organisés en collections d'éléments, ce qui est différent des bases de données relationnelles traditionnelles dans lesquelles plusieurs tables sont créées et liées par des clés étrangères. Une [collection d’éléments](WorkingWithItemCollections.md) est un groupe d’éléments qui partagent la même valeur de clé de partition, mais qui ont des valeurs de clé de tri différentes. Au sein d’une collection d’objets, chaque élément possède une valeur de clé de tri unique qui le distingue des autres éléments. Dans cette optique, utilisons le modèle suivant pour les valeurs `HASH` et `RANGE` pour chaque type d’entité.

Pour commencer, nous utilisons des noms génériques tels que `PK` et `SK` pour stocker différents types d’entités dans la même table et ainsi pérenniser le modèle. Pour une meilleure lisibilité, nous pouvons inclure des préfixes pour indiquer le type de données ou inclure un attribut arbitraire nommé `Entity_type` ou `Type`. Dans l’exemple actuel, nous utilisons une chaîne commençant par `player` pour stocker `player_ID` sous `PK`. Nous utilisons ensuite `entity name#` comme préfixe de `SK` et ajoutons un attribut `Type` pour indiquer le type d’entité auquel appartient cette donnée. Cela nous permet de prendre en charge le stockage d’un plus grand nombre de types d’entités à l’avenir et d’utiliser des technologies avancées telles que la surcharge du GSI et le GSI fragmenté pour prendre en charge un plus grand nombre de modèles d’accès.

Commençons à implémenter les modèles d’accès. Les modèles d’accès tels que l’ajout de joueurs et l’ajout d’équipements peuvent être réalisés au cours de l’opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html). Nous pouvons donc les ignorer. Dans ce document, nous allons nous concentrer sur les modèles d’accès typiques répertoriés ci-dessus.

**Étape 1 : Traitement du modèle d’accès 1 (`getPlayerFriends`)**

Lors de cette étape, nous traitons le modèle d’accès 1 (`getPlayerFriends`). Dans notre conception actuelle, l’amitié est simple et le nombre d’amis dans le jeu est réduit. Par souci de simplicité, nous utilisons un type de données de liste pour stocker les listes d’amis (modélisation 1:1). Dans cette conception, nous utilisons [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) pour satisfaire ce modèle d’accès. Au cours de l’opération `GetItem`, nous fournissons explicitement la valeur de la clé de partition et de la clé de tri pour obtenir un élément spécifique.

Cependant, si un jeu compte un grand nombre d'amis et que les relations entre eux sont complexes (par exemple, les amitiés sont bidirectionnelles avec un composant d'invitation et d'acceptation), il serait nécessaire d'utiliser une many-to-many relation pour enregistrer chaque ami individuellement, afin d'atteindre une taille de liste d'amis illimitée. Et si le changement d'amitié implique d'opérer sur plusieurs éléments en même temps, les transactions DynamoDB peuvent être utilisées pour regrouper plusieurs actions et les soumettre en une all-or-nothing [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html)seule opération. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactGetItems.html)

![\[Schéma many-to-many relationnel complexe pour un profil de jeu de l'entité Friends.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile1.png)


**Étape 2 : Traitement des modèles d’accès 2 (`getPlayerAllProfile`), 3 (`getPlayerAllItems`) et 4 (`getPlayerSpecificItem`) **

Lors de cette étape, nous traitons les modèles d’accès 2 (`getPlayerAllProfile`), 3 (`getPlayerAllItems`) et 4 (`getPlayerSpecificItem`). Ces trois modèles d’accès ont en commun une requête de plage qui utilise l’opération [`Query`](Query.md). En fonction de l’étendue de la requête, une [condition de clé](Query.KeyConditionExpressions.md) et des [expressions de filtre](Query.FilterExpression.md) sont utilisées. Elles sont couramment utilisées dans le développement pratique.

Dans l’opération Query, nous fournissons une valeur unique pour la clé de partition et nous obtenons tous les éléments avec cette valeur de clé de partition. Le modèle d’accès 2 (`getPlayerAllProfile`) est implémenté de cette manière. Nous pouvons éventuellement ajouter une expression de condition de clé de tri, c’est-à-dire une chaîne qui détermine les éléments à lire à partir de la table. Le modèle d’accès 3 (`getPlayerAllItems`) est implémenté en ajoutant la condition clé de la clé de tri begins\$1with`ITEMS#`. De plus, afin de simplifier le développement côté application, nous pouvons utiliser des expressions de filtre pour implémenter le modèle d’accès 4 (`getPlayerSpecificItem`).

Voici un exemple de pseudo-code utilisant une expression de filtre qui filtre les éléments de la catégorie `Weapon` :

```
filterExpression: "ItemType = :itemType"
expressionAttributeValues: {":itemType": "Weapon"}
```

![\[Utilisation de l’opération de requête avec une clé de partition et des conditions de clé de tri pour mettre en œuvre différents modèles d’accès.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile2.png)


**Note**  
Une expression de filtre est appliquée après la fin de l’opération Query, mais avant que les résultats soient renvoyés au client. Par conséquent, une opération Query utilise la même capacité de lecture, qu’une expression de filtre soit présente ou non.

Si le modèle d’accès consiste à interroger un jeu de données volumineux et à filtrer une grande quantité de données pour ne conserver qu’un petit sous-ensemble de données, l’approche appropriée consiste à concevoir la clé de partition et la clé de tri DynamoDB de manière plus efficace. Par exemple, dans l’exemple ci-dessus pour obtenir un certain `ItemType`, s’il existe de nombreux éléments pour chaque joueur et que la recherche d’un certain `ItemType` est un modèle d’accès type, il serait plus efficace d’importer `ItemType` dans `SK` sous forme de clé composite. Le modèle de données ressemblerait à ceci : `ITEMS#ItemType#ItemId`.

**Étape 3 : Traitement des modèles d’accès 5 (`updateCharacterAttributes`) et 6 (`updateItemCount`)**

Lors de cette étape, nous traitons les modèles d’accès 5 (`updateCharacterAttributes`) et 6 (`updateItemCount`). Lorsque le joueur a besoin de modifier son personnage, pour réduire la monnaie ou modifier la quantité d’une arme dans ses objets, utilisez [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) pour implémenter ces modèles d’accès. Pour mettre à jour la monnaie d’un joueur tout en veillant à ce qu’elle ne descende jamais en dessous d’un montant minimum, nous pouvons ajouter un élément [Exemple de commande CLI d’expression de condition DynamoDB](Expressions.ConditionExpressions.md) pour réduire le solde uniquement s’il est supérieur ou égal au montant minimum. Voici un exemple de pseudo-code :

```
UpdateExpression: "SET currency = currency - :amount"
ConditionExpression: "currency >= :minAmount"
```

![\[À utiliser UpdateItem avec une expression conditionnelle pour modifier la devise d'un joueur, en veillant à ce qu'elle ne soit jamais inférieure à un montant défini.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile4-Update-player-Currency.png)


Lors du développement avec DynamoDB et de l’utilisation de [compteurs atomiques](WorkingWithItems.md#WorkingWithItems.AtomicCounters) pour réduire l’inventaire, nous pouvons garantir l’idempotence en utilisant un verrouillage optimiste. Voici un exemple de pseudo-code pour les compteurs atomiques :

```
UpdateExpression: "SET ItemCount = ItemCount - :incr"
expression-attribute-values: '{":incr":{"N":"1"}}'
```

![\[Utilisation d'un compteur atomique pour décrémenter la valeur de ItemCount l'attribut de 5 à 4.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile5-Update-Item-Count.png)


De plus, dans un scénario où le joueur achète un objet avec de la monnaie, l’ensemble du processus doit déduire la monnaie et ajouter un objet en même temps. Nous pouvons utiliser les transactions DynamoDB pour regrouper plusieurs actions et les soumettre en tant all-or-nothing `TransactWriteItems` qu'opération unique. `TransactGetItems` `TransactWriteItems`est une opération d'écriture synchrone et idempotente qui regroupe jusqu'à 100 actions d'écriture en une seule opération. all-or-nothing Les actions sont exécutées de manière atomique, de sorte qu’elles réussissent toutes ou aucune ne réussit. Les transactions contribuent à éliminer le risque de duplication ou de disparition de monnaie. Pour plus d’informations sur les transactions, consultez [Exemple de transactions DynamoDB](transaction-example.md).

Tous les modèles d’accès et la façon dont ils sont traités par la conception du schéma sont résumés dans le tableau ci-dessous :


| Modèle d’accès | table/GSI/LSI de base | Opération | Valeur de la clé de partition | Valeur de clé de tri | Autres conditions/filtres | 
| --- | --- | --- | --- | --- | --- | 
| getPlayerFriends | Table de base | GetItem | PK=PlayerID | SK=“FRIENDS\$1playerID” |  | 
| getPlayerAllProfile | Table de base | Query | PK=PlayerID |  |  | 
| getPlayerAllObjets | Table de base | Query | PK=PlayerID | SK begins\$1with “ITEMS\$1” |  | 
| getPlayerSpecificArticle | Table de base | Query | PK=PlayerID | SK begins\$1with “ITEMS\$1” | FilterExpression : "ItemType =:ItemType » expressionAttributeValues : \$1« :ItemType » : « Arme »\$1 | 
| updateCharacterAttributes | Table de base | UpdateItem | PK=PlayerID | SK=“\$1METADATA\$1playerID” | UpdateExpression: « SET currency = currency -:amount » : « devise ConditionExpression >=:minAmount » | 
| updateItemCount | Table de base | UpdateItem | PK=PlayerID | SK =“ITEMS\$1ItemID” | expression de mise à jour : « SET ItemCount = ItemCount -:incr » expression-attribute-values : '\$1» :incr » : \$1"N » ⁄1"\$1\$1'  | 

## Schéma final de profil de jeu
<a name="data-modeling-schema-gaming-profile-final-schema"></a>

Voici la conception du schéma final. Pour télécharger cette conception de schéma sous forme de fichier JSON, consultez les exemples [DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/GamingPlayerProfiles/GamePlayerProfilesSchema.json) sur. GitHub

**Table de base :**

![\[Conception finale du schéma d’une table contenant les résultats des mises en œuvre de modèles d’accès précédentes.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/GamingProfile6-FinalSchema.png)


## Utilisation de NoSQL Workbench avec cette conception de schéma
<a name="data-modeling-schema-gaming-profile-nosql"></a>

Vous pouvez importer ce schéma final dans [NoSQL Workbench](workbench.md), un outil visuel qui fournit des fonctionnalités de modélisation des données, de visualisation des données et de développement des requêtes pour DynamoDB, afin d’explorer et de modifier davantage votre nouveau projet. Pour commencer, procédez comme suit :

1. Téléchargez NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Télécharger NoSQL Workbench pour DynamoDB](workbench.settingup.md).

1. Téléchargez le fichier de schéma JSON répertorié ci-dessus, qui est déjà au format du modèle NoSQL Workbench.

1. Importez le fichier de schéma JSON dans NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Importation d’un modèle de données existant](workbench.Modeler.ImportExisting.md). 

1. Une fois que vous l’avez importé dans NoSQL Workbench, vous pouvez modifier le modèle de données. Pour de plus amples informations, veuillez consulter [Modification d’un modèle de données existant](workbench.Modeler.Edit.md).

# Conception du schéma d’un système de gestion des réclamations dans DynamoDB
<a name="data-modeling-complaint-management"></a>

## Cas d’utilisation métier d’un système de gestion des réclamations
<a name="data-modeling-schema-complaint-management-use-case"></a>

DynamoDB est une base de données parfaitement adaptée à un cas d’utilisation de système de gestion des réclamations (ou centre de contact), car la plupart des modèles d’accès qui y sont associés sont des recherches transactionnelles basées sur des paires clé-valeur. Dans ce scénario, les modèles d’accès types consisteraient à :
+ Créer et mettre à jour des réclamations
+ Transmettre une réclamation à un échelon supérieur (escalade)
+ Créer et lire des commentaires sur une réclamation
+ Recueillir toutes les réclamations d’un client
+ Recueillir tous les commentaires d’un agent et toutes les escalades 

Certains commentaires peuvent s’accompagner de pièces jointes décrivant la réclamation ou la solution. Bien que ces modèles d’accès soient tous de type clé-valeur, d’autres exigences peuvent s’ajouter, comme l’envoi de notifications lorsqu’un nouveau commentaire est ajouté à une réclamation ou l’exécution de requêtes analytiques pour déterminer la répartition hebdomadaire des réclamations par gravité (ou les performances des agents). La nécessité d’archiver les données relatives aux réclamations trois ans après l’enregistrement de la réclamation pourrait constituer une autre exigence liée à la gestion du cycle de vie ou à la conformité.

## Diagramme de l’architecture du système de gestion des réclamations
<a name="data-modeling-schema-complaint-management-ad"></a>

Le schéma suivant illustre l’architecture du système de gestion des réclamations. Ce schéma montre les différentes Service AWS intégrations utilisées par le système de gestion des plaintes.

![\[Flux de travail combiné permettant de répondre aux exigences non transactionnelles à l’aide d’intégrations avec plusieurs Services AWS.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-1-AD.jpg)


Outre les modèles d’accès transactionnel de type clé-valeur que nous traiterons ultérieurement dans la section sur la modélisation de données DynamoDB, nous sommes en présence de trois exigences non transactionnelles. Le diagramme d’architecture ci-dessus peut être décomposé en trois flux de travail distincts, à savoir :

1. Envoyer une notification lorsqu’un nouveau commentaire est ajouté à une réclamation

1. Exécuter des requêtes analytiques sur les données hebdomadaires

1. Archiver les données de plus de trois ans

Examinons de plus près chacun d’eux.

**Envoyer une notification lorsqu’un nouveau commentaire est ajouté à une réclamation**

Nous pouvons utiliser le flux de travail ci-dessous pour répondre à cette exigence :

![\[Flux de travail permettant d’invoquer des fonctions Lambda pour envoyer des notifications basées sur les changements enregistrés par DynamoDB Streams.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-2-Workflow1.jpg)


[Flux DynamoDB](Streams.md) est un mécanisme de capture des modifications de données qui enregistre toutes les activités d’écriture de vos tables DynamoDB. Vous pouvez configurer des fonctions Lambda pour qu’elles se déclenchent pour tout ou partie de ces modifications. Un [filtre d’événements](https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html) peut être configuré au niveau des déclencheurs Lambda afin de filtrer les événements qui n’ont aucun rapport direct avec le cas d’utilisation. Dans ce cas, nous pouvons utiliser un filtre pour déclencher Lambda uniquement lorsqu’un nouveau commentaire est ajouté et envoyer une notification aux adresses e-mail voulues, qui peuvent être récupérées depuis [AWS  Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html) ou tout autre magasin d’informations d’identification.

**Exécuter des requêtes analytiques sur les données hebdomadaires**

DynamoDB est adapté aux charges de travail principalement axées sur le traitement transactionnel en ligne (OLTP). Pour les 10 à 20 % de modèles d’accès restants soumis à des exigences analytiques, les données peuvent être exportées vers S3 à l’aide de la fonctionnalité gérée [Exporter vers Amazon S3](S3DataExport.HowItWorks.md) sans que cela n’impacte le trafic en direct de la table DynamoDB. Examinez le flux de travail ci-dessous :

![\[Flux de travail permettant d’invoquer régulièrement une fonction Lambda pour stocker les données DynamoDB dans un compartiment Amazon S3.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-3-Workflow2.jpg)


[Amazon EventBridge](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-what-is) peut être utilisé pour déclencher dans AWS Lambda les délais prévus : il vous permet de configurer une expression cron pour que l'appel Lambda ait lieu périodiquement. Lambda peut invoquer l’appel de l’API `ExportToS3` et stocker les données DynamoDB dans S3. Un moteur SQL comme [Amazon Athena](https://docs.aws.amazon.com/athena/latest/ug/what-is) peut ensuite accéder à ces données S3 afin d’exécuter des requêtes analytiques sur les données DynamoDB sans affecter la charge de travail transactionnelle en direct de la table. Voici un exemple de requête Athena qui vise à déterminer le nombre de réclamations par niveau de gravité :

```
SELECT Item.severity.S as "Severity", COUNT(Item) as "Count"
FROM "complaint_management"."data"
WHERE NOT Item.severity.S = ''
GROUP BY Item.severity.S ;
```

Cette requête Athena renvoie le résultat suivant : 

![\[Résultats de la requête Athena indiquant le nombre de réclamations pour les niveaux de gravité P3, P2 et P1.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-4-Athena.png)


**Archiver les données de plus de trois ans**

Vous pouvez tirer parti de la fonctionnalité DynamoDB [Durée de vie (TTL)](TTL.md) pour supprimer les données obsolètes de votre table DynamoDB sans frais supplémentaires (sauf dans le cas des réplicas de tables globales pour la version (actuelle) 2019.11.21, où les suppressions TTL répliquées dans d’autres régions consomment de la capacité d’écriture). Ces données apparaissent et peuvent être utilisées par des flux DynamoDB pour être archivées dans Amazon S3. Voici comment se présente le flux de travail pour cette exigence :

![\[Flux de travail permettant d’archiver les anciennes données dans un compartiment Amazon S3 à l’aide de la fonctionnalité TTL et de DynamoDB Streams.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-5-Workflow3.jpg)


## Diagramme des relations entre entités du système de gestion des réclamations
<a name="data-modeling-schema-complaint-management-erd"></a>

Il s’agit du diagramme des relations entre entités (ERD) que nous allons utiliser pour la conception du schéma du système de gestion des réclamations. 

![\[Diagramme des relations entre entités du système de gestion des réclamations présentant les entités Client, Réclamation, Commentaire et Agent.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-6-ERD.jpg)


## Modèles d’accès du système de gestion des réclamations
<a name="data-modeling-schema-complaint-management-access-patterns"></a>

Voici les modèles d’accès que nous allons prendre en considération pour la conception du schéma de gestion des réclamations.

1. createComplaint

1. updateComplaint

1. updateSeveritybyComplaintID

1. getComplaintByID de plainte

1. addCommentByID de plainte

1. getAllCommentsByComplaintID

1. getLatestCommentByComplaintID

1. obtenir un identifiant de IDAnd plainte AComplaintby du client

1. getAllComplaintsByCustomerID

1. escalateComplaintByID de plainte

1. getAllEscalatedRéclamations

1. getEscalatedComplaintsByAgentID (ordre du plus récent au plus ancien)

1. getCommentsByAgentID (entre deux dates)

## Évolution de la conception du schéma du système de gestion des réclamations
<a name="data-modeling-schema-complaint-management-design-evolution"></a>

S’agissant d’un système de gestion des réclamations, la plupart des modèles d’accès sont centrés sur la réclamation en tant qu’entité principale. Du fait de sa cardinalité élevée, `ComplaintID` assurera une répartition uniforme des données dans les partitions sous-jacentes, et ce sera également le critère de recherche le plus courant pour nos modèles d’accès identifiés. Par conséquent, il est judicieux d’utiliser `ComplaintID` comme de clé de partition dans cet ensemble de données.

**Étape 1 : Traitement des modèles d’accès 1 (`createComplaint`), 2 (`updateComplaint`), 3 (`updateSeveritybyComplaintID`) et 4 (`getComplaintByComplaintID`) **

Nous pouvons utiliser une valeur de clé de tri générique appelée « metadata » (ou « AA ») pour stocker les informations propres aux réclamations, telles que `CustomerID`, `State`, `Severity` et `CreationDate`. Nous utilisons des opérations singleton avec `PK=ComplaintID` et `SK=“metadata”` pour effectuer les opérations suivantes :

1. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_PutItem.html) pour créer une nouvelle réclamation

1. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_UpdateItem.html) pour mettre à jour la gravité ou d’autres champs dans les métadonnées de la réclamation

1. [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) pour récupérer les métadonnées de la réclamation

![\[Clé primaire, clé de tri et valeurs d’attribut, telles que customer_id et gravité, pour un élément de réclamation.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-7-Step1.png)


**Étape 2 : Traitement du modèle d’accès 5 (`addCommentByComplaintID`)**

Ce modèle d'accès nécessite un modèle de one-to-many relation entre une plainte et les commentaires sur la plainte. Nous allons employer ici la technique du [partitionnement vertical](data-modeling-blocks.md#data-modeling-blocks-vertical-partitioning) pour utiliser une clé de tri et créer une collection d’éléments avec différents types de données. Dans le cas des modèles d’accès 6 (`getAllCommentsByComplaintID`) et 7 (`getLatestCommentByComplaintID`), nous savons que les commentaires devront être triés par ordre chronologique. Nous savons également que plusieurs commentaires pourront être reçus simultanément, ce qui signifie que nous pouvons utiliser la technique de [clé de tri composite](data-modeling-blocks.md#data-modeling-blocks-composite) pour ajouter l’heure et `CommentID` dans l’attribut de clé de tri.

Pour faire face à ce risque de collision de commentaires, il pourrait être envisagé d’accroître la granularité de l’horodatage ou d’ajouter un nombre incrémentiel en guise de suffixe à la place de `Comment_ID`. Dans ce cas, nous allons faire précéder la valeur de clé de tri du préfixe « comm\$1 » pour les éléments correspondant aux commentaires afin de permettre les opérations basées sur une plage.

Nous devons également vérifier que `currentState` dans les métadonnées de la réclamation reflète l’état d’ajout d’un nouveau commentaire. L’ajout d’un commentaire peut indiquer que la réclamation a été affectée à un agent, qu’elle n’a pas été résolue, etc. Afin de regrouper l'ajout de commentaires et la mise à jour de l'état actuel dans les métadonnées de la plainte, nous utiliserons l'[TransactWriteItems](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_TransactWriteItems.html)API d'une all-or-nothing manière ou d'une autre. L’état de la table qui en résulte ressemble désormais à ceci :

![\[Tableau permettant de stocker une plainte avec ses commentaires sous forme de one-to-many relation à l'aide d'une clé de tri composite.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-8-Step2.png)


Ajoutons quelques données supplémentaires dans la table et ajoutons également `ComplaintID` sous la forme d’un champ distinct de notre `PK` pour pérenniser le modèle au cas où nous aurions besoin d’index supplémentaires sur `ComplaintID`. Notez également que certains commentaires peuvent contenir des pièces jointes que nous stockerons dans Amazon Simple Storage Service et conserverons uniquement leurs références ou URLs dans DynamoDB. Dans un souci d’optimisation des coûts et des performances, il est recommandé de garder la base de données transactionnelle aussi légère que possible. Les données ressemblent désormais à ceci :

![\[Tableau contenant les métadonnées des réclamations et les données de tous les commentaires associés à chaque réclamation.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-9-Step3.png)


**Étape 3 : Traitement des modèles d’accès 6 (`getAllCommentsByComplaintID`) et 7 (`getLatestCommentByComplaintID`)**

Pour obtenir tous les commentaires relatifs à une réclamation, nous pouvons utiliser l’opération de requête ([`query`](Query.md)) avec la condition `begins_with` au niveau de la clé de tri. Plutôt que de consommer de la capacité de lecture supplémentaire pour lire l’entrée de métadonnées et d’avoir à filtrer les résultats pertinents, cette condition de clé de tri nous permet de lire uniquement ce dont nous avons besoin. Par exemple, une opération de requête avec `PK=Complaint123` et `SK` begins\$1with `comm#` renverrait ce qui suit tout en ignorant l’entrée de métadonnées :

![\[Résultat de l’opération de requête utilisant une condition de clé de tri qui affiche uniquement les commentaires d’une réclamation.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-10-Step4.png)


Puisque nous avons besoin du commentaire le plus récent concernant une réclamation du modèle 7 (`getLatestCommentByComplaintID`), utilisons deux paramètres de requête supplémentaires :

1. `ScanIndexForward` doit être défini sur False pour que les résultats soient triés par ordre décroissant

1. `Limit` doit être défini sur 1 pour obtenir le commentaire (unique) le plus récent

Comme pour le modèle d’accès 6 (`getAllCommentsByComplaintID`), nous ignorons l’entrée de métadonnées en utilisant `begins_with` `comm#` comme condition de clé de tri. Vous pouvez désormais exécuter le modèle d'accès 7 sur ce modèle à l'aide de l'opération de requête avec `PK=Complaint123` et `SK=begins_with comm#``ScanIndexForward=False`, et `Limit` 1. L’élément ciblé suivant est renvoyé en résultat :

![\[Résultat d’une opération de requête utilisant une condition de clé de tri afin d’obtenir le dernier commentaire d’une réclamation.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-11-Step5.png)


Ajoutons d’autres données fictives au tableau.

![\[Tableau contenant des données fictives permettant d’obtenir les derniers commentaires sur les réclamations reçues.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-12-Step6.png)


**Étape 4 : Traitement des modèles d’accès 8 (`getAComplaintbyCustomerIDAndComplaintID`) et 9 (`getAllComplaintsByCustomerID`)**

Les modèles d’accès 8 (`getAComplaintbyCustomerIDAndComplaintID`) et 9 (`getAllComplaintsByCustomerID`) introduisent un nouveau critère de recherche : `CustomerID`. Pour le récupérer à partir de la table existante, il faut passer par une opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Scan.html) coûteuse afin de lire toutes les données et filtrer ensuite les éléments pertinents pour le `CustomerID` en question. Nous pouvons améliorer l’efficacité de cette recherche en créant un [index secondaire global (GSI)](GSI.md) avec `CustomerID` comme clé de partition. En tenant compte de la one-to-many relation entre le client et les plaintes ainsi que du modèle d'accès 9 (`getAllComplaintsByCustomerID`), `ComplaintID` ce serait le bon candidat pour la clé de tri.

Voici comment se présenteraient les données dans le GSI :

![\[GSI avec un modèle de one-to-many relation pour recevoir toutes les plaintes par un CustomerID spécifique.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-13-Step4-GSI.png)


 Voici un exemple de requête sur ce GSI pour le modèle d’accès 8 (`getAComplaintbyCustomerIDAndComplaintID`) : `customer_id=custXYZ`, `sort key=Complaint1321`. Le résultat serait le suivant :

![\[Résultat d’une opération de requête sur un GSI permettant d’obtenir les données d’une réclamation spécifique d’un client donné.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-14-Step4-8.png)


Pour obtenir toutes les réclamations d’un client pour le modèle d’accès 9 (`getAllComplaintsByCustomerID`), la requête sur le GSI serait `customer_id=custXYZ` comme condition de clé de partition. Le résultat serait le suivant :

![\[Résultat de l’opération de requête utilisant une condition de clé de partition permettant d’obtenir toutes les réclamations d’un client donné.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-15-Step4-9.png)


**Étape 5 : Traitement du modèle d’accès 10 (`escalateComplaintByComplaintID`)**

Cet accès introduit la notion d’escalade. Pour transmettre une plainte à un échelon supérieur, nous pouvons utiliser `UpdateItem` pour ajouter des attributs tels que `escalated_to` et `escalation_time` à l’élément de métadonnées de réclamation existant. DynamoDB offre une conception de schéma flexible, ce qui signifie qu’un ensemble d’attributs qui ne correspondent pas à une clé peut être uniforme ou discret entre différents éléments. Voici un exemple :

`UpdateItem with PK=Complaint1444, SK=metadata`

![\[Résultat de la mise à jour des métadonnées des plaintes à l'aide d'une opération d' UpdateItem API.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-16-Step5.png)


**Étape 6 : Traitement des modèles d’accès 11 (`getAllEscalatedComplaints`) et 12 (`getEscalatedComplaintsByAgentID`)**

Sur l’ensemble complet de données, seules quelques réclamations devraient faire l’objet d’une escalade. Par conséquent, la création d’un index sur les attributs liés à l’escalade aboutirait à des recherches efficaces et à un stockage GSI économique. Pour cela, nous pouvons tirer parti de la technique de l’[index fragmenté](data-modeling-blocks.md#data-modeling-blocks-sparse-index). Voici à quoi ressemblerait le GSI avec la clé de partition `escalated_to` et la clé de tri `escalation_time` :

![\[Conception GSI utilisant les attributs liés à l’escalade, escalated_to et escalation_time.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-17-Step6.png)


Pour obtenir toutes les réclamations ayant fait l’objet d’une escalade pour le modèle d’accès 11 (`getAllEscalatedComplaints`), il nous suffit d’analyser ce GSI. Notez que cette analyse sera performante et économique du fait de la taille du GSI. Pour obtenir les réclamations ayant fait l’objet d’une escalade pour un agent déterminé (modèle d’accès 12 (`getEscalatedComplaintsByAgentID`)), la clé de partition serait `escalated_to=agentID` et nous définirions `ScanIndexForward` sur `False` pour un ordre de tri du plus récent au plus ancien.

**Étape 7 : Traitement du modèle d’accès 13 (`getCommentsByAgentID`)**

Pour le dernier modèle d’accès, nous devons effectuer une recherche selon une nouvelle dimension : `AgentID`. Nous avons également besoin d’un ordre chronologique pour lire les commentaires entre deux dates. Nous créons donc un GSI avec `agent_id` comme clé de partition et `comm_date` comme clé de tri. Voici comment se présentent les données dans ce GSI :

![\[Conception GSI permettant de rechercher les commentaires d’un agent donné triés en fonction de la date du commentaire.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-18.png)


Voici un exemple de requête sur ce GSI : `partition key agentID=AgentA` et `sort key=comm_date between (2023-04-30T12:30:00, 2023-05-01T09:00:00)`, et en voici le résultat :

![\[Résultat d’une requête utilisant une clé de partition et une clé de tri sur un GSI.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-19.png)


Tous les modèles d’accès et la façon dont ils sont traités par la conception du schéma sont résumés dans le tableau ci-dessous :


| Modèle d’accès | table/GSI/LSI de base | Opération | Valeur de la clé de partition | Valeur de clé de tri | Autres conditions/filtres | 
| --- | --- | --- | --- | --- | --- | 
| createComplaint | Table de base | PutItem | PK=complaint\$1id | SK=metadata |  | 
| updateComplaint | Table de base | UpdateItem | PK=complaint\$1id | SK=metadata |  | 
| updateSeveritybyComplaintID | Table de base | UpdateItem | PK=complaint\$1id | SK=metadata |  | 
| getComplaintByID de plainte | Table de base | GetItem | PK=complaint\$1id | SK=metadata |  | 
| addCommentByID de plainte | Table de base | TransactWriteItems | PK=complaint\$1id | SK=metadata, SK=comm\$1comm\$1date\$1comm\$1id |  | 
| getAllCommentsByComplaintID | Table de base | Query | PK=complaint\$1id | SK begins\$1with "comm\$1" |  | 
| getLatestCommentByComplaintID | Table de base | Query | PK=complaint\$1id | SK begins\$1with "comm\$1" | scan\$1index\$1forward=False, Limit 1 | 
| obtenir un identifiant de IDAnd plainte AComplaintby du client | Customer\$1complaint\$1GSI | Query | customer\$1id=customer\$1id | complaint\$1id = complaint\$1id |  | 
| getAllComplaintsByCustomerID | Customer\$1complaint\$1GSI | Query | customer\$1id=customer\$1id | N/A |  | 
| escalateComplaintByID de plainte | Table de base | UpdateItem | PK=complaint\$1id | SK=metadata |  | 
| getAllEscalatedRéclamations | Escalations\$1GSI | Analyser | N/A | N/A |  | 
| getEscalatedComplaintsByAgentID (ordre du plus récent au plus ancien) | Escalations\$1GSI | Query | escalated\$1to=agent\$1id | N/A | scan\$1index\$1forward=False | 
| getCommentsByAgentID (entre deux dates) | Agents\$1Comments\$1GSI | Query | agent\$1id=agent\$1id | SK between (date1, date2) |  | 

## Schéma final du système de gestion des réclamations
<a name="data-modeling-schema-complaint-management-final-schema"></a>

Voici les conceptions du schéma final. Pour télécharger cette conception de schéma sous forme de fichier JSON, consultez les exemples [DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/ComplainManagement/ComplaintManagementSchema.json) sur. GitHub

**Table de base**

![\[Conception de la table de base avec métadonnées de réclamation.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-20-Complaint_management_system.png)


**Customer\$1Complaint\$1GSI**

![\[Conception GSI indiquant les réclamations d’un client donné.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-21-Customer_Complaint_GSI.png)


**Escalations\$1GSI**

![\[Conception GSI indiquant les attributs liés à l’escalade.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-22-Escalations_GSI.png)


**Agents\$1Comments\$1GSI**

![\[Conception GSI indiquant les commentaires faits par un agent donné.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ComplaintManagement-23-Comments_GSI.png)


## Utilisation de NoSQL Workbench avec cette conception de schéma
<a name="data-modeling-schema-complaint-management-nosql"></a>

Vous pouvez importer ce schéma final dans [NoSQL Workbench](workbench.md), un outil visuel qui fournit des fonctionnalités de modélisation des données, de visualisation des données et de développement des requêtes pour DynamoDB, afin d’explorer et de modifier davantage votre nouveau projet. Pour commencer, procédez comme suit :

1. Téléchargez NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Télécharger NoSQL Workbench pour DynamoDB](workbench.settingup.md).

1. Téléchargez le fichier de schéma JSON répertorié ci-dessus, qui est déjà au format du modèle NoSQL Workbench.

1. Importez le fichier de schéma JSON dans NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Importation d’un modèle de données existant](workbench.Modeler.ImportExisting.md). 

1. Une fois que vous l’avez importé dans NoSQL Workbench, vous pouvez modifier le modèle de données. Pour de plus amples informations, veuillez consulter [Modification d’un modèle de données existant](workbench.Modeler.Edit.md).

# Conception d’un schéma de paiements récurrents dans DynamoDB
<a name="data-modeling-schema-recurring-payments"></a>

## Cas d’utilisation métier de paiements récurrents
<a name="data-modeling-schema-recurring-payments-use-case"></a>

Ce cas d’utilisation traite de l’utilisation de DynamoDB pour implémenter un système de paiements récurrents. Le modèle de données comprend les entités suivantes : *accounts* (comptes), *subscriptions* (abonnements) et *receipts* (reçus). Notre cas d’utilisation présente les spécificités suivantes :
+ Chaque *compte* peut être composé de plusieurs *abonnements*
+ L’*abonnement* présente un `NextPaymentDate` qui correspond à la prochaine date de paiement et un `NextReminderDate`qui correspond à la date où un e-mail de rappel doit être envoyé au client
+ Un élément est stocké et mis à jour pour l’*abonnement* une fois que le paiement a été traité (la taille moyenne des éléments est d’environ 1 Ko et le débit dépend du nombre de *comptes* et d’*abonnements*)
+ Par ailleurs, le processeur de *paiements* crée un *reçu* dans le cadre du processus, qui est stocké dans la table avec un délai d’expiration défini à l’aide d’un attribut [TTL](TTL.md)

## Diagramme des relations entre entités pour les paiements récurrents
<a name="data-modeling-schema-recurring-payments-erd"></a>

Voici le diagramme des relations entre entités (ERD) que nous allons utiliser pour la conception du schéma de paiements récurrents.

![\[ERD de système de paiements récurrents indiquant les entités suivantes : Account, Subscription et Receipt.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-1-ERD.png)


## Modèles d’accès du système de paiements récurrents
<a name="data-modeling-schema-recurring-payments-access-patterns"></a>

Voici les modèles d’accès que nous allons prendre en considération pour la conception du schéma du système de paiements récurrents.

1. `createSubscription`

1. `createReceipt`

1. `updateSubscription`

1. `getDueRemindersByDate`

1. `getDuePaymentsByDate`

1. `getSubscriptionsByAccount`

1. `getReceiptsByAccount`

## Conception du schéma pour les paiements récurrents
<a name="data-modeling-schema-recurring-payments-design-evolution"></a>

Les noms génériques `PK` et `SK` sont utilisés pour les attributs de clé afin de permettre le stockage de différents types d’entités dans la même table, comme les entités account, subscription et receipt. Pour commencer, l’utilisateur crée un abonnement et accepte ainsi de payer un montant le même jour de chaque mois en contrepartie d’un produit. Il a la possibilité de choisir le jour du mois auquel le paiement sera effectué. Un rappel sera également envoyé avant l’exécution du paiement. L’application fait appel à deux tâches de traitement par lots qui s’exécutent chaque jour : l’une qui envoie les rappels programmés à cette date et l’autre qui traite les paiements prévus ce même jour.

**Étape 1 : Traitement du modèle d’accès 1 (`createSubscription`)**

Le modèle d’accès 1 (`createSubscription`) est utilisé pour créer dans un premier temps l’abonnement ; les détails comme `SKU`, `NextPaymentDate`, `NextReminderDate` et `PaymentDetails` sont également définis. Cette étape indique l’état de la table pour un seul compte avec un seul abonnement. Il peut y avoir plusieurs abonnements dans la collection d'articles, il s'agit donc d'une one-to-many relation.

![\[Modèle de tableau présentant les détails de l’abonnement d’un compte.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-2-Step1.png)


**Étape 2 : Traitement des modèles d’accès 2 (`createReceipt`) et 3 (`updateSubscription`)**

Le modèle d’accès 2 (`createReceipt`) est utilisé pour créer l’élément de reçu. Une fois que le paiement mensuel a été effectué, le processeur de paiements écrit un reçu dans la table de base. Il peut y avoir plusieurs reçus dans la collection d'articles, il s'agit donc d'une one-to-many relation. Le processeur de paiements met également à jour l’élément d’abonnement (modèle d’accès 3 (`updateSubscription`)) afin de mettre à jour `NextReminderDate` ou `NextPaymentDate` pour le mois suivant.

![\[Mise à jour des détails de réception et des éléments d’abonnement pour afficher la date du prochain rappel d’abonnement.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-3-Step2.png)


**Étape 3 : Traitement du modèle d’accès 4 (`getDueRemindersByDate`)**

L’application traite les rappels de paiement par lots pour la date du jour. L’application doit donc accéder aux abonnements selon une autre dimension : la date et non le compte. Pour ce cas d’utilisation, il est judicieux d’utiliser un [index secondaire global (GSI)](GSI.md). Dans cette étape, nous allons ajouter l’index `GSI-1`, qui utilise `NextReminderDate` en guise de clé de partition de GSI. Il n’est pas nécessaire de répliquer tous les éléments. Ce GSI étant un [index fragmenté](data-modeling-blocks.md#data-modeling-blocks-sparse-index), les éléments de reçus ne sont pas répliqués. Il n’est pas non plus nécessaire de projeter tous les attributs ; il suffit d’inclure un sous-ensemble d’attributs. L’image ci-dessous montre le schéma de `GSI-1`, qui contient les informations dont l’application a besoin pour envoyer l’e-mail de rappel.

![\[Schéma GSI-1 avec des détails, tels que l’adresse e-mail, dont l’application a besoin pour envoyer un e-mail de rappel.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-4-Step3.png)


**Étape 4 : Traitement du modèle d’accès 5 (`getDuePaymentsByDate`)**

L’application traite les paiements par lots pour la journée en cours de la même manière qu’elle le fait pour les rappels. Nous ajoutons `GSI-2` dans cette étape, et `NextPaymentDate` fait office de clé de partition de GSI. Il n’est pas nécessaire de répliquer tous les éléments. Ce GSI est un index fragmenté, car les éléments de reçus ne sont pas répliqués. L’image ci-dessous montre le schéma de `GSI-2`.

![\[Schéma GSI-2 avec détails pour traiter les paiements. NextPaymentDate est la clé de partition pour GSI-2.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-5-Step4.png)


**Étape 5 : Traitement des modèles d’accès 6 (`getSubscriptionsByAccount`) et 7 (`getReceiptsByAccount`)**

L’application peut récupérer tous les abonnements d’un compte en exécutant une [requête](Query.md) sur la table de base qui cible l’identifiant du compte (`PK`) et utilise l’opérateur de plage pour obtenir tous les éléments pour lesquels `SK` commence par « SUB\$1 ». De même, l’application peut utiliser la même structure de requête pour récupérer tous les reçus en utilisant un opérateur de plage afin d’obtenir tous les éléments pour lesquels `SK` commence par « REC\$1 ». Cela nous permet de satisfaire les modèles d’accès 6 (`getSubscriptionsByAccount`) et 7 (`getReceiptsByAccount`). L’application utilise ces modèles d’accès pour permettre aux utilisateurs de consulter leurs abonnements en cours et leurs anciens reçus des six derniers mois. Lors de cette étape, aucune modification n’est apportée au schéma de table, et nous pouvons voir ci-dessous que seuls les éléments d’abonnement sont ciblés dans le modèle d’accès 6 (`getSubscriptionsByAccount`).

![\[Résultat de l’opération de requête sur la table de base. Indique l’abonnement d’un compte spécifique.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-6-Step5.png)


Tous les modèles d’accès et la façon dont ils sont traités par la conception du schéma sont résumés dans le tableau ci-dessous :


| Modèle d’accès | table/GSI/LSI de base | Opération | Valeur de la clé de partition | Valeur de clé de tri | 
| --- | --- | --- | --- | --- | 
| createSubscription | Table de base | PutItem | ACC\$1account\$1id | SUB\$1<SUBID>\$1SKU<SKUID> | 
| createReceipt | Table de base | PutItem | ACC\$1account\$1id | REC\$1< > \$1SKU RecieptDate <SKUID> | 
| updateSubscription | Table de base | UpdateItem | ACC\$1account\$1id | SUB\$1<SUBID>\$1SKU<SKUID> | 
| getDueRemindersByDate | GSI-1 | Query | <NextReminderDate> |  | 
| getDuePaymentsByDate | GSI-2 | Query | <NextPaymentDate> |  | 
| getSubscriptionsByCompte | Table de base | Query | ACC\$1account\$1id | SK begins\$1with “SUB\$1” | 
| getReceiptsByCompte | Table de base | Query | ACC\$1account\$1id | SK begins\$1with “REC\$1” | 

## Schéma final pour les paiements récurrents
<a name="data-modeling-schema-recurring-payments-final-schema"></a>

Voici les conceptions du schéma final. Pour télécharger cette conception de schéma sous forme de fichier JSON, consultez les exemples [DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/blob/master/schema_design/SchemaExamples/ReocurringPayments/ReocurringPaymentsSchema.json) sur. GitHub

**Table de base**

![\[Conception du tableau de base affichant les informations du compte, ainsi que les détails de son abonnement et de sa réception.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-7-Base.png)


**GSI-1**

![\[Schéma GSI-1 avec les détails de l'abonnement, tels que l'adresse e-mail et. NextPaymentDate\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-8-GSI1.png)


**GSI-2**

![\[Schéma GSI-2 avec détails de paiement, tels PaymentAmount que et. PaymentDay\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/ReoccurringPayments-9-GSI2.png)


## Utilisation de NoSQL Workbench avec cette conception de schéma
<a name="data-modeling-schema-recurring-payments-nosql"></a>

Vous pouvez importer ce schéma final dans [NoSQL Workbench](workbench.md), un outil visuel qui fournit des fonctionnalités de modélisation des données, de visualisation des données et de développement des requêtes pour DynamoDB, afin d’explorer et de modifier davantage votre nouveau projet. Pour commencer, procédez comme suit :

1. Téléchargez NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Télécharger NoSQL Workbench pour DynamoDB](workbench.settingup.md).

1. Téléchargez le fichier de schéma JSON répertorié ci-dessus, qui est déjà au format du modèle NoSQL Workbench.

1. Importez le fichier de schéma JSON dans NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Importation d’un modèle de données existant](workbench.Modeler.ImportExisting.md). 

1. Une fois que vous l’avez importé dans NoSQL Workbench, vous pouvez modifier le modèle de données. Pour de plus amples informations, veuillez consulter [Modification d’un modèle de données existant](workbench.Modeler.Edit.md).

# Surveillance des mises à jour du statut d’un appareil dans DynamoDB
<a name="data-modeling-device-status"></a>

Ce cas d’utilisation décrit l’utilisation de DynamoDB pour surveiller les mises à jour du statut d’un appareil (ou les changements d’état d’un appareil) dans DynamoDB.

## Cas d’utilisation
<a name="data-modeling-schema-device-status-use-case"></a>

Dans les cas d’utilisation IoT (une fabrique intelligente, par exemple), de nombreux appareils doivent être surveillés par les opérateurs, qui envoient régulièrement leur statut ou leurs journaux à un système de surveillance. En cas de problème avec un appareil, son statut passe de *normal* à *warning*. Il existe différents niveaux ou statuts de journalisation en fonction de la gravité et du type de comportement anormal de l’appareil. Le système désigne ensuite un opérateur chargé de vérifier l’appareil et celui-ci peut faire remonter le problème à son superviseur si nécessaire.

Les modèles d’accès types pour ce système incluent :
+ Créer une entrée de journal pour un appareil
+ Obtenir tous les journaux pour un état d’appareil spécifique en affichant d’abord les journaux les plus récents
+ Obtenir tous les journaux pour un opérateur donné entre deux dates
+ Obtenir tous les journaux qui ont été remontés pour un superviseur donné
+ Obtenir tous les journaux qui ont été remontés avec un état d’appareil spécifique pour un superviseur donné
+ Obtenir tous les journaux qui ont été remontés avec un état d’appareil spécifique pour un superviseur donné à une date spécifique

## Diagramme des relations entre entités
<a name="data-modeling-schema-device-status-erd"></a>

Voici le diagramme des relations entre entités (ERD) que nous allons utiliser pour surveiller les mises à jour du statut d’un appareil.

![\[Diagramme des relations entre entités des mises à jour de l’état d’un appareil. Indique les entités : appareil et opérateur.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-1-ERD.jpg)


## Modèles d’accès
<a name="data-modeling-schema-device-status-access-patterns"></a>

Voici les modèles d’accès que nous allons prendre en compte pour surveiller les mises à jour du statut d’un appareil.

1. `createLogEntryForSpecificDevice`

1. `getLogsForSpecificDevice`

1. `getWarningLogsForSpecificDevice`

1. `getLogsForOperatorBetweenTwoDates`

1. `getEscalatedLogsForSupervisor`

1. `getEscalatedLogsWithSpecificStatusForSupervisor`

1. `getEscalatedLogsWithSpecificStatusForSupervisorForDate`

## Évolution de la conception du schéma
<a name="data-modeling-schema-device-status-design-evolution"></a>

**Étape 1 : Traitement des modèles d’accès 1 (`createLogEntryForSpecificDevice`) et 2 (`getLogsForSpecificDevice`)**

L’unité de mise à l’échelle d’un système de suivi des appareils est constituée d’appareils individuels. Dans ce système, un `deviceID` identifie un appareil de manière unique. `deviceID` est donc un bon candidat pour la clé de partition. Chaque appareil envoie régulièrement des informations au système de suivi (toutes les cinq minutes environ). Cet ordre fait de la date un critère de tri logique et, par conséquent, la clé de tri. Dans ce cas, les exemples de données ressembleraient à ce qui suit :

![\[Table permettant d’enregistrer l’état de plusieurs appareils. DeviceID est la clé primaire et la date de mise à jour de l’état est la clé de tri.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-2-Step1.png)


Pour extraire les entrées de journal d’un appareil spécifique, il est possible d’exécuter une opération [query](Query.md) avec la clé de partition `DeviceID="d#12345"`.

**Étape 2 : Traitement du modèle d’accès 3 (`getWarningLogsForSpecificDevice`)**

Étant donné que `State` est un attribut non clé, le traitement du modèle d’accès 3 avec le schéma actuel nécessiterait une [expression de filtre](Query.FilterExpression.md). Dans DynamoDB, les expressions de filtre sont appliquées après la lecture des données à l’aide d’expressions de condition de clé. Par exemple, si nous devions extraire les journaux d’avertissement pour `d#12345`, l’opération de requête avec la clé de partition `DeviceID="d#12345"` lirait quatre éléments du tableau ci-dessus, puis filtrerait le seul élément sans l’état *warning*. Cette approche n’est pas efficace à grande échelle. L’expression de filtre peut être un bon moyen d’exclure les éléments interrogés si le ratio des éléments exclus est faible ou si la requête est rarement exécutée. Toutefois, dans les cas où de nombreux éléments sont extraits d’une table et que la majorité d’entre eux sont filtrés, nous pouvons continuer à faire évoluer la conception de notre table afin qu’elle s’exécute plus efficacement.

Nous allons changer la façon de traiter ce modèle d’accès en utilisant des [clés de tri composites](data-modeling-blocks.md#data-modeling-blocks-composite). Vous pouvez importer des exemples de données depuis [DeviceStateLog\$13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_3.json) où la clé de tri est remplacée par. `State#Date` Cette clé de tri est la composition des attributs `State`, `#` et `Date`. Dans cet exemple, `#` est utilisé comme délimiteur. Les données ressemblent désormais à ce qui suit : 

![\[Données de mise à jour de l’état de l’appareil, d#12345, extraites à l’aide de la clé de tri composite State#Date.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-3-Step2.png)


Pour extraire uniquement les journaux d’avertissement d’un appareil, la requête devient plus ciblée avec ce schéma. La condition de clé pour la requête utilise la clé de partition `DeviceID="d#12345"` et la clé de tri `State#Date begins_with “WARNING”`. Cette requête ne lira que les trois éléments pertinents avec l’état *warning*.

**Étape 3 : Traitement du modèle d’accès 4 (`getLogsForOperatorBetweenTwoDates`)**

Vous pouvez importer [DeviceStateLog\$14.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_4.json) D où l'`Operator`attribut a été ajouté à la `DeviceStateLog` table avec des exemples de données.

![\[DeviceStateLog conception de table avec attribut Operator pour obtenir les journaux d'un opérateur entre des dates spécifiques.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-4-Step3.png)


Étant donné que `Operator` n’est pas une clé de partition actuellement, il n’existe aucun moyen d’effectuer une recherche directe clé-valeur dans cette table en fonction de `OperatorID`. Nous devrons créer une [collection d’éléments](WorkingWithItemCollections.md) avec un index secondaire global sur `OperatorID`. Étant donné que le modèle d’accès nécessite une recherche basée sur les dates, Date est donc l’attribut de clé de tri pour l’[index secondaire global (GSI)](GSI.md). Voici à quoi ressemble désormais le GSI :

![\[Conception d’un GSI avec OperatorID et Date comme clé de partition et clé de tri permettant d’obtenir les journaux d’un opérateur spécifique.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-5-Step3.png)


Pour le modèle d’accès 4 (`getLogsForOperatorBetweenTwoDates`), vous pouvez interroger ce GSI avec la clé de partition `OperatorID=Liz` et la clé de tri `Date` entre `2020-04-11T05:58:00` et `2020-04-24T14:50:00`.

![\[Interrogation sur un GSI en utilisant OperatorID et Date pour obtenir les journaux d’un opérateur entre deux dates.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-6-GSI1_1.png)


**Étape 4 : Traitement des modèles d’accès 5 (`getEscalatedLogsForSupervisor`), 6 (`getEscalatedLogsWithSpecificStatusForSupervisor`) et 7 (`getEscalatedLogsWithSpecificStatusForSupervisorForDate`)**

Nous utiliserons un [index fragmenté](data-modeling-blocks.md#data-modeling-blocks-sparse-index) pour traiter ces modèles d’accès.

Les index secondaires globaux sont fragmentés par défaut, de sorte que seuls les éléments de la table de base contenant les attributs de clé primaire de l’index apparaîtront réellement dans l’index. Il s’agit d’une autre façon d’exclure les éléments qui ne sont pas pertinents pour le modèle d’accès modélisé.

Vous pouvez importer [DeviceStateLog\$16.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/device-state-log/json/DeviceStateLog_6.json) où l'`EscalatedTo`attribut a été ajouté à la `DeviceStateLog` table avec des exemples de données. Comme mentionné précédemment, tous les journaux ne font pas l’objet d’une remontée à un superviseur.

![\[Conception GSI avec l' EscalatedTo attribut permettant d'obtenir tous les journaux escaladés pour un superviseur.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-7-Step4.png)


Vous pouvez maintenant créer un GSI où `EscalatedTo` est la clé de partition et `State#Date` est la clé de tri. Notez que seuls les éléments qui possèdent à la fois les attributs `EscalatedTo` et `State#Date` apparaissent dans l’index.

![\[Conception GSI pour obtenir tous les objets dotés des attributs EscalatedTo et State #Date.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-8-Step4.png)


Les autres modèles d’accès sont résumés comme suit :

    Pour le modèle d'accès 5 (getEscalatedLogsForSupervisor), vous pouvez effectuer une requête sur les escalations GSI avec la clé EscalatedTo de partition ="Sara »   Pour le modèle d'accès 6 (getEscalatedLogsWithSpecificStatusForSupervisor), vous pouvez effectuer une requête sur les escalations GSI avec la clé de partition EscalatedTo ="Sara » et la clé de tri State \$1Date begins\$1with « WARNING »    Pour le modèle d'accès 7 (getEscalatedLogsWithSpecificStatusForSupervisorForDate), vous pouvez effectuer une requête sur les escalations GSI avec la clé de partition EscalatedTo ="Sara » et la clé de tri State \$1Date begins\$1with « \$12020 -04-27 » WARNING4    

Tous les modèles d’accès et la façon dont ils sont traités par la conception du schéma sont résumés dans le tableau ci-dessous :


| Modèle d’accès | table/GSI/LSI de base | Opération | Valeur de la clé de partition | Valeur de clé de tri | Autres conditions/filtres | 
| --- | --- | --- | --- | --- | --- | 
| createLogEntryForSpecificDevice | Table de base | PutItem | DeviceID=deviceId | State\$1Date=state\$1date |  | 
| getLogsForSpecificDevice | Table de base | Query | DeviceID=deviceId | State\$1Date begins\$1with "state1\$1" | ScanIndexForward = Faux | 
| getWarningLogsForSpecificDevice | Table de base | Query | DeviceID=deviceId | State\$1Date begins\$1with "WARNING" |  | 
| getLogsForOperatorBetweenTwoDates | GSI-1 | Query | Operator=operatorName | Date between date1 and date2 |  | 
| getEscalatedLogsForSupervisor | GSI-2 | Query | EscalatedTo= Nom du superviseur |  |  | 
| getEscalatedLogsWithSpecificStatusForSupervisor | GSI-2 | Query | EscalatedTo= Nom du superviseur | State\$1Date begins\$1with "state1\$1" |  | 
| getEscalatedLogsWithSpecificStatusForSupervisorForDate | GSI-2 | Query | EscalatedTo= Nom du superviseur | State\$1Date begins\$1with "state1\$1date1" |  | 

## Schéma final
<a name="data-modeling-schema-device-status-final-schema"></a>

Voici les conceptions du schéma final. Pour télécharger cette conception de schéma sous forme de fichier JSON, consultez les exemples [DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples) sur. GitHub

**Table de base**

![\[Conception d’une table de base avec des métadonnées d’état de l’appareil, telles que Device ID, State et Date.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-9-Table.png)


**GSI-1**

![\[Conception GSI-1. Indique la clé primaire et les attributs : DeviceID, State#Date et State.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-10-GSI1.png)


**GSI-2**

![\[Conception GSI-2. Indique la clé primaire et les attributs : DeviceID, Operator, Date et State.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/DeviceStatus-11-GSI2.png)


## Utilisation de NoSQL Workbench avec cette conception de schéma
<a name="data-modeling-schema-device-status-nosql"></a>

Vous pouvez importer ce schéma final dans [NoSQL Workbench](workbench.md), un outil visuel qui fournit des fonctionnalités de modélisation des données, de visualisation des données et de développement des requêtes pour DynamoDB, afin d’explorer et de modifier davantage votre nouveau projet. Pour commencer, procédez comme suit :

1. Téléchargez NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Télécharger NoSQL Workbench pour DynamoDB](workbench.settingup.md).

1. Téléchargez le fichier de schéma JSON répertorié ci-dessus, qui est déjà au format du modèle NoSQL Workbench.

1. Importez le fichier de schéma JSON dans NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Importation d’un modèle de données existant](workbench.Modeler.ImportExisting.md). 

1. Une fois que vous l’avez importé dans NoSQL Workbench, vous pouvez modifier le modèle de données. Pour de plus amples informations, veuillez consulter [Modification d’un modèle de données existant](workbench.Modeler.Edit.md).

# Utilisation de DynamoDB comme magasin de données pour un magasin en ligne
<a name="data-modeling-online-shop"></a>

Ce cas d’utilisation décrit l’utilisation de DynamoD comme magasin de données pour une boutique en ligne (ou boutique virtuelle).

## Cas d’utilisation
<a name="data-modeling-schema-online-shop"></a>

Une boutique en ligne permet aux utilisateurs de parcourir différents produits et de les acheter par la suite. Sur la base de la facture générée, le client peut payer à l’aide d’un code de réduction ou d’une carte-cadeau, puis régler le montant restant par carte de crédit. Les produits achetés seront collectés dans l’un des nombreux entrepôts et seront expédiés à l’adresse indiquée. Les modèles d’accès types d’une boutique en ligne incluent :
+ Obtenir un client pour un customerId donné
+ Obtenir un produit pour un productId donné
+ Obtenir un entrepôt pour un warehouseId donné
+ Obtenez un inventaire de produits pour tous les entrepôts à l’aide d’un productId
+ Obtenir une commande pour un orderId donné
+ Obtenir tous les produits pour un orderId donné
+ Obtenir une facture pour un orderId donné
+ Obtenir toutes les expéditions pour un orderId donné
+ Obtenir toutes les commandes pour un productId donné et une plage de dates donnée
+ Obtenir une facture pour un invoiceId donné
+ Obtenir tous les paiements pour un invoiceId donné
+ Obtenir les détails d’une expédition pour un shipmentId donné
+ Obtenir toutes les expéditions pour un warehouseId donné
+ Obtenir l’inventaire de tous les produits pour un warehouseId donné
+ Obtenir toutes les factures pour un customerId donné et une plage de dates donnée
+ Obtenir tous les produits commandés par un customerId donné pour une plage de dates donnée

## Diagramme des relations entre entités
<a name="data-modeling-schema-online-shop-erd"></a>

Voici le diagramme des relations entre entités (ERD) que nous utiliserons pour modéliser DynamoDB en tant que magasin de données pour une boutique en ligne.

![\[Diagramme des relations entre entités (ERD) pour le modèle de données d’un magasin en ligne avec des entités telles que le produit, la commande, le paiement et le client.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-1-ERD.png)


## Modèles d’accès
<a name="data-modeling-schema-online-shop-access-patterns"></a>

Voici les modèles d’accès que nous allons prendre en compte lors de l’utilisation de DynamoDB comme magasin de données pour une boutique en ligne.

1. `getCustomerByCustomerId`

1. `getProductByProductId`

1. `getWarehouseByWarehouseId`

1. `getProductInventoryByProductId`

1. `getOrderDetailsByOrderId`

1. `getProductByOrderId`

1. `getInvoiceByOrderId`

1. `getShipmentByOrderId`

1. `getOrderByProductIdForDateRange`

1. `getInvoiceByInvoiceId`

1. `getPaymentByInvoiceId`

1. `getShipmentDetailsByShipmentId`

1. `getShipmentByWarehouseId`

1. `getProductInventoryByWarehouseId`

1. `getInvoiceByCustomerIdForDateRange`

1. `getProductsByCustomerIdForDateRange`

## Évolution de la conception du schéma
<a name="data-modeling-schema-online-shop-design-evolution"></a>

En utilisant[NoSQL Workbench pour DynamoDB](workbench.md), import [AnOnlineShop\$11.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_1.json) pour créer un nouveau modèle de données appelé `AnOnlineShop` et une nouvelle table appelée. `OnlineShop` Notez que nous utilisons les noms génériques `PK` et `SK` pour la clé de partition et la clé de tri. Cette méthode permet de stocker différents types d’entités dans la même table.

**Étape 1 : Traitement du modèle d’accès 1 (`getCustomerByCustomerId`)**

Importez [AnOnlineShop\$12.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_2.json) pour gérer le modèle d'accès 1 ()`getCustomerByCustomerId`. Étant donné que certaines entités n’ont aucune relation avec d’autres entités, nous utiliserons la même valeur de `PK` et `SK` pour ces entités. Dans les exemples de données, notez que les clés utilisent le préfixe `c#` afin de distinguer `customerId` des autres entités qui seront ajoutées ultérieurement. Cette méthode est également répétée pour d’autres entités. 

Pour traiter ce modèle d’accès, il est possible d’utiliser l’opération [https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_GetItem.html) avec `PK=customerId` et `SK=customerId`.

**Étape 2 : Traitement du modèle d’accès 2 (`getProductByProductId`)**

Importez [AnOnlineShop\$13.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_3.json) pour adresser le modèle d'accès 2 (`getProductByProductId`) pour l'`product`entité. Les entités de produit utilisent le préfixe `p#` et le même attribut de clé de tri a été utilisé pour stocker `customerID` et `productID`. Un nom générique et le [partitionnement vertical](data-modeling-blocks.md#data-modeling-blocks-vertical-partitioning) nous permettent de créer ces ensembles d’éléments pour une conception de table unique efficace. 

Pour traiter ce modèle d’accès, il est possible d’utiliser l’opération `GetItem` avec `PK=productId` et `SK=productId`.

**Étape 3 : Traitement du modèle d’accès 3 (`getWarehouseByWarehouseId`)**

Importez [AnOnlineShop\$14.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_4.json) pour adresser le modèle d'accès 3 (`getWarehouseByWarehouseId`) pour l'`warehouse`entité. Les entités `customer`, `product` et `warehouse` ont actuellement été ajoutées à la même table. Ils se distinguent par l’utilisation de préfixes et de l’attribut `EntityType`. Un attribut de type (ou l’utilisation d’un préfixe) améliore la lisibilité du modèle. La lisibilité serait affectée si nous stockions simplement des caractères alphanumériques IDs pour différentes entités dans le même attribut. Il serait difficile de distinguer une entité d’une autre en l’absence de ces identifiants. 

Pour traiter ce modèle d’accès, il est possible d’utiliser l’opération `GetItem` avec `PK=warehouseId` et `SK=warehouseId`.

**Table de base :**

![\[Conception de tables DynamoDB avec préfixes EntityType et permettant d'obtenir les données de l'entrepôt par leur identifiant.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-2-Step3.png)


**Étape 4 : Traitement du modèle d’accès 4 (`getProductInventoryByProductId`)**

Importez [AnOnlineShop\$15.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_5.json) pour adresser le modèle d'accès 4 ()`getProductInventoryByProductId`. `warehouseItem`L'entité est utilisée pour suivre le nombre de produits dans chaque entrepôt. Cet élément est habituellement mis à jour lorsqu’un produit est ajouté ou retiré d’un entrepôt. Comme on le voit dans l'ERD, il existe une many-to-many relation entre `product` et`warehouse`. Ici, la one-to-many relation de `product` à `warehouse` est modélisée comme`warehouseItem`. Plus tard, la one-to-many relation de `warehouse` à `product` sera également modélisée. 

Le modèle d’accès 4 peut être traité à l’aide d’une requête sur `PK=ProductId` et `SK begins_with “w#“`. 

Pour plus d’informations sur `begins_with()` et d’autres expressions pouvant être appliquées aux clés de tri, consultez [Expressions de condition de clé](Query.KeyConditionExpressions.md).

**Table de base :**

![\[Conception de table pour effectuer des requêtes ProductID et warehouseId afin de suivre l’inventaire des produits dans un entrepôt donné.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-3-Step4.png)


**Étape 5 : Traitement des modèles d’accès 5 (`getOrderDetailsByOrderId`) et 6 (`getProductByOrderId`)**

Ajoutez quelques `warehouse` éléments supplémentaires `customer` à la table en important [AnOnlineShop\$16.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_6.json). `product` Ensuite, importez [AnOnlineShop\$17.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_7.json) pour créer une collection d'objets `order` capable de traiter les modèles d'accès 5 (`getOrderDetailsByOrderId`) et 6 (`getProductByOrderId`). Vous pouvez voir la one-to-many relation entre les entités OrderItem `order` et les `product` modéliser sous forme d'entités. 

Pour traiter le modèle d’accès 5 (`getOrderDetailsByOrderId`), interrogez la table avec `PK=orderId`. Cette requête fournira toutes les informations relatives à la commande, y compris le `customerId` et les produits commandés.

**Table de base :**

![\[Conception de table pour effectuer une requête à l’aide de orderId pour obtenir des informations sur tous les produits commandés.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-4-Step5.png)


Pour traiter le modèle d’accès 6 (`getProductByOrderId`), nous devons lire les produits uniquement dans `order`. Pour ce faire, interrogez la table avec `PK=orderId` et `SK begins_with “p#”`.

**Table de base :**

![\[Conception de table pour effectuer une requête à l’aide de orderId et productId pour obtenir les produits d’une commande.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-5-Step5.png)


**Étape 6 : Traitement du modèle d’accès 7 (`getInvoiceByOrderId`)**

Importez [AnOnlineShop\$18.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_8.json) pour ajouter une `invoice` entité à la collection d'articles de *commande afin* de gérer le modèle d'accès 7 ()`getInvoiceByOrderId`. Pour traiter ce modèle d’accès, il est possible d’utiliser une opération query avec `PK=orderId` et `SK begins_with “i#”`.

**Table de base :**

![\[Conception de tableau avec entité de facture dans la collection d’éléments de commande pour obtenir une facture par orderId.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-6-Step6.png)


**Étape 7 : Traitement du modèle d’accès 8 (`getShipmentByOrderId`)**

Importez [AnOnlineShop\$19.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_9.json) pour ajouter `shipment` des entités à la collection d'articles *de commande afin* de répondre au modèle d'accès 8 ()`getShipmentByOrderId`. Nous développons le même modèle partitionné verticalement en ajoutant d’autres types d’entités dans la conception de table unique. Vous pouvez remarquer que l’ensemble d’éléments *order* contient les différentes relations d’une entité `order` avec les entités `shipment`, `orderItem` et `invoice`. 

Pour obtenir les expéditions par `orderId`, vous pouvez effectuer une opération query avec `PK=orderId` et `SK begins_with “sh#”`.

**Table de base :**

![\[Conception du tableau avec une entité d’expédition ajoutée à la collection des éléments de commande pour obtenir les envois par ID de commande.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-7-Step7.png)


**Étape 8 : Traitement du modèle d’accès 9 (`getOrderByProductIdForDateRange`)**

Nous avons créé un ensemble d’éléments *order* à l’étape précédente. Ce modèle d’accès comporte de nouvelles dimensions de recherche (`ProductID` et `Date`) qui vous obligent à analyser l’ensemble de la table et à filtrer les enregistrements pertinents pour extraire les éléments ciblés. Pour traiter ce modèle d’accès, nous allons devoir créer un [index secondaire global (GSI)](GSI.md). Importez [AnOnlineShop\$110.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_10.json) pour créer une nouvelle collection d'articles à l'aide du GSI qui permet de récupérer les `orderItem` données de plusieurs collections d'articles de *commande*. Les données comportent désormais `GSI1-PK` et `GSI1-SK`, qui seront la clé de partition et la clé de tri de `GSI1`, respectivement. 

DynamoDB renseigne automatiquement les éléments qui contiennent les attributs de clé d’un GSI, de la table au GSI. Il n’est pas nécessaire d’effectuer des insertions manuelles supplémentaires dans le GSI. 

Pour traiter le modèle d’accès 9, exécutez une requête sur `GSI1` avec `GSI1-PK=productId` et `GSI1SK between (date1, date2)`.

**Table de base :**

![\[Conception de table avec un GSI pour obtenir les données de commande de plusieurs collections d’éléments de commande.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-8-Step8-Base.png)


**GSI1:**

![\[Conception GSI avec ProductID et Date comme partition et clés de tri pour obtenir les commandes par ID de produit et par date.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-9-Step8-GSI.png)


**Étape 9 : Traitement des modèles d’accès 10 (`getInvoiceByInvoiceId`) et 11 (`getPaymentByInvoiceId`)**

Importez [AnOnlineShop\$111.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_11.json) pour traiter les modèles d'accès 10 (`getInvoiceByInvoiceId`) et 11 (`getPaymentByInvoiceId`), qui sont tous deux liés à. `invoice` Même s’il s’agit de deux modèles d’accès différents, ils sont réalisés en utilisant la même condition de clé. `Payments` est défini sous la forme d’un attribut avec le type de données de carte sur l’entité `invoice`.

**Note**  
`GSI1-PK` et `GSI1-SK` sont surchargés pour stocker des informations sur différentes entités afin que plusieurs modèles d’accès puissent être utilisés à partir du même GSI. Pour plus d’informations sur la surcharge du GSI, consultez [Surcharge des index secondaires globaux dans DynamoDB](bp-gsi-overloading.md).

Pour traiter le modèle d’accès 10 et 11, interrogez `GSI1` avec `GSI1-PK=invoiceId` et `GSI1-SK=invoiceId`.

**GSI1:**

![\[Conception GSI avec invoiceId à la fois comme partition et clé de tri pour obtenir la facture et le paiement par ID de facture.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-10-Step9.png)


**Étape 10 : Traitement des modèles d’accès 12 (`getShipmentDetailsByShipmentId`) et 13 (`getShipmentByWarehouseId`)**

Importez [AnOnlineShop\$112.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_12.json) pour traiter les modèles d'accès 12 (`getShipmentDetailsByShipmentId`) et 13 (`getShipmentByWarehouseId`). 

Vous pouvez remarquer que les entités `shipmentItem` sont ajoutées à l’ensemble d’éléments *order* sur la table de base afin de pouvoir récupérer tous les détails d’une commande en une seule opération query.

**Table de base :**

![\[Conception du tableau avec une entité shipmentItem dans la collection des éléments de commande pour obtenir tous les détails d’une commande.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-11-Step10.png)


Les clés de `GSI1` partition et de tri ont déjà été utilisées pour modéliser une one-to-many relation entre `shipment` et`shipmentItem`. Pour traiter le modèle d’accès 12 (`getShipmentDetailsByShipmentId`), interrogez `GSI1` avec `GSI1-PK=shipmentId` et `GSI1-SK=shipmentId`.

**GSI1:**

![\[GSI1 conception avec ShipmentID comme partition et clé de tri pour obtenir les détails de l'expédition par numéro d'expédition.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-12-Step10-GSI.png)


Nous devrons créer un autre GSI (`GSI2`) pour modéliser la nouvelle one-to-many relation entre `warehouse` et `shipment` pour le modèle d'accès 13 (`getShipmentByWarehouseId`). Pour traiter ce modèle d’accès, interrogez `GSI2` avec `GSI2-PK=warehouseId` et `GSI2-SK begins_with “sh#”`.

**GSI2:**

![\[GSI2 conception avec WarehouseID et ShipmentID comme clés de partition et de tri pour obtenir les envois par entrepôt.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-13-Step10-GSI2.png)


**Étape 11 : Traitement des modèles d’accès 14 (`getProductInventoryByWarehouseId`), 15 (`getInvoiceByCustomerIdForDateRange`) et 16 (`getProductsByCustomerIdForDateRange`)**

Importez [AnOnlineShop\$113.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_13.json) pour ajouter des données relatives au prochain ensemble de modèles d'accès. Pour traiter le modèle d’accès 14 (`getProductInventoryByWarehouseId`), interrogez `GSI2` avec `GSI2-PK=warehouseId` et `GSI2-SK begins_with “p#”`.

**GSI2:**

![\[GSI2 conception avec WarehouseID et ProductID comme partition et clés de tri pour adresser le modèle d'accès 14.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-14-Step11-GSI2.png)


Pour traiter le modèle d’accès 15 (`getInvoiceByCustomerIdForDateRange`), interrogez `GSI2` avec `GSI2-PK=customerId` et `GSI2-SK between (i#date1, i#date2)`.

**GSI2:**

![\[GSI2 conception avec CustomerID et plage de dates de facturation comme partition et clés de tri pour répondre au modèle d'accès 15.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-15-Step11-GSI2.png)


Pour traiter le modèle d’accès 16 (`getProductsByCustomerIdForDateRange`), interrogez `GSI2` avec `GSI2-PK=customerId` et `GSI2-SK between (p#date1, p#date2)`.

**GSI2:**

![\[GSI2 conception avec CustomerID et plage de dates du produit comme partition et clés de tri pour répondre au modèle d'accès 16\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-16-Step11-GSI2.png)


**Note**  
Dans [NoSQL Workbench](workbench.md), les *facettes* représentent les différents modèles d’accès aux données d’une application pour DynamoDB. Les facettes vous permettent d’afficher un sous-ensemble de données dans une table, sans avoir à voir les enregistrements qui ne répondent pas aux contraintes de la facette. Les facettes sont considérées comme un outil de modélisation de données visuelles et n’existent pas en tant que construction utilisable dans DynamoDB, car elles sont purement une aide à la modélisation des modèles d’accès.   
Importez [AnOnlineShop\$1facets.json](https://github.com/aws-samples/amazon-dynamodb-design-patterns/blob/master/examples/an-online-shop/json/AnOnlineShop_facets.json) pour voir les facettes de ce cas d'utilisation.

Tous les modèles d’accès et la façon dont ils sont traités par la conception du schéma sont résumés dans le tableau ci-dessous :


| Modèle d’accès | table/GSI/LSI de base | Opération | Valeur de la clé de partition | Valeur de clé de tri | 
| --- | --- | --- | --- | --- | 
| getCustomerByCustomerId | Table de base | GetItem |  PK=customerId | SK=customerId | 
| getProductByProductId | Table de base | GetItem |  PK=productId | SK=productId | 
| getWarehouseByWarehouseId | Table de base | GetItem |  PK=warehouseId | SK=warehouseId | 
| getProductInventoryByProductId | Table de base | Query |  PK=productId | SK begins\$1with "w\$1" | 
| getOrderDetailsByOrderId | Table de base | Query |  PK=orderId |  | 
| getProductByOrderId | Table de base | Query |  PK=orderId | SK begins\$1with "p\$1" | 
| getInvoiceByOrderId |  Table de base | Query |  PK=orderId | SK begins\$1with "i\$1" | 
| getShipmentByOrderId |  Table de base | Query |  PK=orderId | SK begins\$1with "sh\$1" | 
| getOrderByProductIdForDateRange |  GSI1 | Query |  PK=productId | SK between date1 and date2 | 
| getInvoiceByInvoiceId |  GSI1 | Query |  PK=invoiceId | SK=invoiceId | 
| getPaymentByInvoiceId |  GSI1 | Query |  PK=invoiceId | SK=invoiceId | 
| getShipmentDetailsByShipmentId |  GSI1 | Query |  PK=shipmentId | SK=shipmentId | 
| getShipmentByWarehouseId |  GSI2 | Query |  PK=warehouseId | SK begins\$1with "sh\$1" | 
| getProductInventoryByWarehouseId |  GSI2 | Query |  PK=warehouseId | SK begins\$1with "p\$1" | 
| getInvoiceByCustomerIdForDateRange |  GSI2 | Query |  PK=customerId | SK between i\$1date1 and i\$1date2 | 
| getProductsByCustomerIdForDateRange |  GSI2 | Query |  PK=customerId | SK between p\$1date1 and p\$1date2 | 

### Schéma final pour la boutique en ligne
<a name="data-modeling-schema-online-store-final-schema"></a>

Voici les conceptions du schéma final. Pour télécharger cette conception de schéma sous forme de fichier JSON, consultez la section Modèles de conception [DynamoDB](https://github.com/aws-samples/aws-dynamodb-examples/tree/master/schema_design/SchemaExamples) sur. GitHub

**Table de base**

![\[Schéma final de la table de base pour une boutique en ligne avec des attributs tels que EntityName et le nom.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-17-Final-BaseTable.png)


**GSI1**

![\[GSI1 Schéma final de la table de base d'une boutique en ligne avec des attributs, tels que EntityType.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-18-Final-GSI1.png)


**GSI2**

![\[GSI2 Schéma final de la table de base d'une boutique en ligne avec des attributs, tels que EntityType.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/DataModeling/OnlineShop-19-Final-GSI2.png)


## Utilisation de NoSQL Workbench avec cette conception de schéma
<a name="data-modeling-schema-online-shop-nosql"></a>

Vous pouvez importer ce schéma final dans [NoSQL Workbench](workbench.md), un outil visuel qui fournit des fonctionnalités de modélisation des données, de visualisation des données et de développement des requêtes pour DynamoDB, afin d’explorer et de modifier davantage votre nouveau projet. Pour commencer, procédez comme suit :

1. Téléchargez NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Télécharger NoSQL Workbench pour DynamoDB](workbench.settingup.md).

1. Téléchargez le fichier de schéma JSON répertorié ci-dessus, qui est déjà au format du modèle NoSQL Workbench.

1. Importez le fichier de schéma JSON dans NoSQL Workbench. Pour de plus amples informations, veuillez consulter [Importation d’un modèle de données existant](workbench.Modeler.ImportExisting.md). 

1. Une fois que vous l’avez importé dans NoSQL Workbench, vous pouvez modifier le modèle de données. Pour de plus amples informations, veuillez consulter [Modification d’un modèle de données existant](workbench.Modeler.Edit.md).

# Bonnes pratiques de modélisation des données relationnelles dans DynamoDB
<a name="bp-relational-modeling"></a>

Cette section présente les bonnes pratiques de modélisation des données relationnelles dans Amazon DynamoDB Tout d’abord, nous présentons les concepts traditionnels de modélisation des données. Ensuite, nous décrivons les avantages liés à l’utilisation de DynamoDB par rapport aux systèmes de gestion de base de données relationnelle traditionnels, en expliquant en quoi cela dispense d’utiliser des opérations JOIN et réduit les frais généraux. 

Nous expliquons ensuite comment concevoir une table DynamoDB qui se met à l’échelle de manière efficace. Enfin, nous proposons un exemple de modélisation de données relationnelles dans DynamoDB.

**Topics**
+ [Modèles de base de données relationnelle traditionnels](#SQLtoNoSQL.relational-modeling2)
+ [Comment DynamoDB élimine le besoin d’opérations JOIN](#bp-relational-modeling-joins)
+ [Comment les transactions DynamoDB éliminent la surcharge pour le processus d’écriture](#bp-relational-modeling-transactions)
+ [Premiers pas pour la modélisation des données relationnelles dans DynamoDB](bp-modeling-nosql.md)
+ [Exemple de modélisation des données relationnelles dans DynamoDB](bp-modeling-nosql-B.md)

## Modèles de base de données relationnelle traditionnels
<a name="SQLtoNoSQL.relational-modeling2"></a>

Un système de gestion de base de données relationnelle (SGBDR) traditionnel stocke les données dans une structure relationnelle normalisée. L’objectif du modèle de données relationnel est de réduire la duplication des données (par le biais de la normalisation) afin de garantir l’intégrité référentielle et de réduire les anomalies des données. 

Le schéma suivant est un exemple de modèle de données relationnel pour une application de saisie de commandes générique. Cette application prend en charge un schéma de ressources humaines qui soutient les systèmes de support d’exploitation et d’activités d’un fabricant fictif.

![\[Exemple de schéma de SGBDR.\]](http://docs.aws.amazon.com/fr_fr/amazondynamodb/latest/developerguide/images/RDBMS.png)


En tant que service de base de données non relationnelle, DynamoDB offre de nombreux avantages par rapport aux systèmes de gestion de base de données relationnelle traditionnels. 

## Comment DynamoDB élimine le besoin d’opérations JOIN
<a name="bp-relational-modeling-joins"></a>

Un SGBDR utilise un langage SQL (Structure Query Language) pour renvoyer les données à l’application. Du fait de la normalisation du modèle de données, les requêtes de ce type nécessitent généralement l’utilisation de l’opérateur `JOIN` pour associer les données d’une ou plusieurs tables.

Par exemple, pour générer une liste d’articles de bon de commande triés selon la quantité en stock dans tous les entrepôts pouvant livrer chacun d’entre eux, vous pouvez exécuter la requête SQL suivante sur le schéma précédent.

```
SELECT * FROM Orders
  INNER JOIN Order_Items ON Orders.Order_ID = Order_Items.Order_ID
  INNER JOIN Products ON Products.Product_ID = Order_Items.Product_ID
  INNER JOIN Inventories ON Products.Product_ID = Inventories.Product_ID
  ORDER BY Quantity_on_Hand DESC
```

Les requêtes SQL de ce type peuvent fournir une API flexible pour accéder aux données, mais elles nécessitent un volume de traitement important. Chaque jointure contenue dans la requête accentue la complexité d’exécution de la requête, car les données de chaque table doivent être préparées, puis assemblées pour renvoyer le jeu de résultats. 

La taille des tables et la présence d’index dans les colonnes jointes sont d’autres facteurs qui peuvent avoir une incidence sur le temps d’exécution des requêtes. La requête précédente initie des requêtes complexes sur plusieurs tables, puis trie le jeu de résultats.

L’élimination du besoin de `JOINs` est au cœur de la modélisation des données NoSQL. C’est pourquoi nous avons conçu DynamoDB pour qu’il soit compatible avec Amazon.com, et c’est pourquoi DynamoDB peut fournir des performances constantes à n’importe quelle échelle. Compte tenu de la complexité d'exécution des requêtes SQL et des `JOINs` performances du SGBDR ne sont pas constantes à grande échelle. Cela entraîne des problèmes de performances à mesure que les applications des clients se développent.

Bien que la normalisation des données réduise la quantité de données stockées sur le disque, les ressources les plus limitées qui ont un impact sur les performances sont souvent le temps processeur et la latence du réseau. 

DynamoDB est conçu pour minimiser ces deux contraintes en éliminant `JOINs` (et en encourageant la dénormalisation des données) et en optimisant l’architecture de la base de données afin de répondre entièrement à une requête d’application avec une seule requête pour un élément. Ces qualités permettent à DynamoDB d’offrir des performances en millisecondes à un chiffre à n’importe quelle échelle. Cela s’explique par le fait que la complexité d’exécution des opérations DynamoDB est constante, quelle que soit la taille des données, pour les modèles d’accès courants.

## Comment les transactions DynamoDB éliminent la surcharge pour le processus d’écriture
<a name="bp-relational-modeling-transactions"></a>

L’utilisation de transactions pour écrire dans un schéma normalisé est un autre facteur de ralentissement d’un SGBDR. Comme indiqué dans l’exemple, les structures de données relationnelles utilisées par la plupart des applications de traitement de transaction en ligne (OLTP) doivent être décomposées et réparties dans plusieurs tables logiques lorsqu’elles sont stockées dans un SGBDR. 

Par conséquent, une infrastructure de transaction conforme à ACID est nécessaire pour éviter les conditions de concurrence et les problèmes d’intégrité des données pouvant avoir lieu si une application tente de lire un objet qui est en cours d’écriture. Une telle structure de transaction, lorsqu’elle est associée à un schéma relationnel, peut surcharger considérablement le processus d’écriture.

L’implémentation des transactions dans DynamoDB permet d’éviter les problèmes de mise à l’échelle qui sont souvent constatés avec un SGBDR. Pour ce faire, DynamoDB émet une transaction sous la forme d’un appel d’API unique et limite le nombre d’éléments accessibles dans cette même transaction. Les transactions de longue durée peuvent entraîner des problèmes opérationnels en bloquant les données de manière prolongée, voire perpétuelle, car la transaction n’est jamais clôturée. 

Pour éviter de tels problèmes dans DynamoDB, les transactions ont été implémentées avec deux opérations d’API distinctes : `TransactWriteItems` et `TransactGetItems`. La sémantique de début et de fin de ces opérations d’API n’est pas commune dans un SGBDR. De plus, DynamoDB impose une limite d’accès à 100 éléments dans une même transaction dans une optique similaire qui est d’empêcher les transactions de longue durée. Pour en savoir plus sur les transactions DynamoDB, consultez [Utilisation de transactions](transactions.md).

Ce sont les raisons pour lesquelles, lorsque votre activité exige une réponse à faible latence pour des requêtes à fort trafic, il est généralement judicieux, d’un point de vue technique et économique, de tirer parti des avantages d’un système NoSQL. Amazon DynamoDB aide à résoudre les problèmes qui restreignent la capacité de mise à l’échelle d’un système relationnel en les évitant.

Les performances d’un SGBDR peinent généralement à évoluer pour les raisons suivantes :
+ Elle utilise des jointures coûteuses pour reconstituer les vues de résultats de requête requises.
+ Elle normalise les données et les stocke dans plusieurs tables qui nécessitent plusieurs requêtes pour l’écriture sur disque.
+ Elle entraîne généralement les coûts de performances d’un système de transaction conforme à ACID.

DynamoDB se met à l’échelle coorectement pour les raisons suivantes :
+ Grâce à la flexibilité de son schéma, DynamoDB peut stocker des données hiérarchiques complexes au sein d’un seul élément.
+ Une conception de clé composite permet à ce service de stocker les éléments liés proches les uns des autres dans la même table.
+ Les transactions sont effectuées dans une même opération. Le nombre d’éléments accessibles est limité à 100 pour éviter les opérations de longue durée.

Les requêtes sur le magasin de données deviennent beaucoup plus simples, en prenant souvent la forme suivante :

```
SELECT * FROM Table_X WHERE Attribute_Y = "somevalue"
```

DynamoDB exécute beaucoup moins de tâches pour renvoyer les données demandées, comparé au SGBDR de l’exemple précédent.

# Premiers pas pour la modélisation des données relationnelles dans DynamoDB
<a name="bp-modeling-nosql"></a>

**Note**  
Pour concevoir un système NoSQL, il faut un autre état d’esprit que pour un SGBDR. Pour un SGBDR, vous pouvez créer un modèle de données normalisé sans réfléchir aux modèles d’accès. Vous pouvez l’étendre ultérieurement, pour répondre à de nouvelles questions et de nouveaux besoins d’interrogation. En revanche, dans Amazon DynamoDB, vous ne devez pas commencer à concevoir votre schéma tant que vous ne savez pas à quelle problématique celui-ci doit répondre. Il est absolument essentiel d’identifier au préalable les problèmes métier et les cas d’utilisation de l’application.

Pour commencer à concevoir une table DynamoDB qui pourra être efficacement mise à l’échelle, vous devez d’abord effectuer plusieurs étapes pour identifier les modèles d’accès qui sont requis par les systèmes de support d’exploitation et de support d’activités (OSS/BSS) que celle-ci doit prendre en charge :
+ Pour les nouvelles applications, consultez des témoignages d’utilisateurs sur les activités et les objectifs. Documentez les différents cas d’utilisation que vous identifiez et analysez les modèles d’accès dont ceux-ci ont besoin.
+ Pour des applications existantes, analysez les journaux de requêtes pour découvrir comment le système est actuellement utilisé et identifier les principaux modèles d’accès.

Après avoir terminé ce processus, vous devriez obtenir une liste ressemblant à ce qui suit :


**Modèles d'accès pour l'application de saisie de commandes**  

| Motif \$1 | Description du modèle d'accès | 
| --- | --- | 
| 1 | Rechercher les détails des employés par ID d’employé | 
| 2 | Interroger les détails des employés par nom d’employé | 
| 3 | Trouver le (s) numéro (s) de téléphone d'un employé | 
| 4 | Trouver le (s) numéro (s) de téléphone d'un client | 
| 5 | Obtenez des commandes pour les clients dans un intervalle de dates | 
| 6 | Afficher toutes les commandes ouvertes dans un intervalle de dates | 
| 7 | Voir tous les employés embauchés récemment | 
| 8 | Trouvez tous les employés de Warehouse | 
| 9 | Obtenez tous les articles en commande pour le produit | 
| 10 | Obtenez des stocks de produits dans tous les entrepôts | 
| 11 | Attirez des clients par le biais d'un représentant commercial | 
| 12 | Recevez les commandes par le représentant du compte | 
| 13 | Trouvez des employés avec le titre du poste | 
| 14 | Obtenez l'inventaire par produit et par entrepôt | 
| 15 | Obtenez l'inventaire total des produits | 

Dans une application réelle, votre liste peut être beaucoup plus longue. Mais cette collection représente toute la complexité d’un modèle de requête que vous pourriez trouver dans un environnement de production.

Une approche moderne de la conception de schémas DynamoDB utilise des principes orientés agrégats, regroupant les données en fonction de modèles d'accès plutôt que de limites d'entités rigides. Cette approche prend en compte plusieurs modèles de conception :
+ *Conception de table unique* : utilisation de clés de tri composites, d'index secondaires globaux surchargés et de modèles de listes de contiguïté pour stocker plusieurs types d'entités dans une seule table
+ *Conception multi-tables* - Utilisation de tables séparées pour les entités présentant des caractéristiques opérationnelles indépendantes et une faible corrélation d'accès, avec une stratégie GSIs pour les requêtes entre entités
+ *Conception agrégée* - Intégrer les données associées lorsqu'elles sont toujours accessibles ensemble (Commande \$1 OrderItems) ou utilisation de collections d'articles pour identifier les relations (Produit \$1 Inventaire)

Le choix entre ces approches dépend de vos modèles d'accès spécifiques, des caractéristiques des données et des exigences opérationnelles. Vous pouvez utiliser ces éléments pour structurer les données afin qu’une application puisse récupérer ce dont elle a besoin pour un modèle d’accès donné à l’aide d’une requête unique sur une table ou un index.

**Note**  
Le choix entre une conception à table unique ou à tables multiples dépend de vos besoins spécifiques. La conception à table unique fonctionne bien lorsque les entités présentent une forte corrélation d'accès et des caractéristiques opérationnelles similaires. La conception à plusieurs tables est préférable lorsque les entités ont des exigences opérationnelles indépendantes, des modèles d'accès différents ou lorsque vous avez besoin de limites opérationnelles claires. L'exemple présenté dans ce guide illustre une approche multi-tables avec agrégation et dénormalisation stratégiques.

Pour utiliser NoSQL Workbench pour DynamoDB afin de mieux visualiser votre conception de clé de partition, consultez [Création de modèles de données avec NoSQL Workbench](workbench.Modeler.md).

# Exemple de modélisation des données relationnelles dans DynamoDB
<a name="bp-modeling-nosql-B"></a>

Cet exemple décrit comment modéliser des données relationnelles dans Amazon DynamoDB. La conception de la table DynamoDB correspond au schéma de saisie d'ordre relationnel illustré dans. [Modélisation relationnelle](bp-relational-modeling.md) Cette conception utilise plusieurs tables spécialisées plutôt qu'une seule liste de contiguïté, fournissant des limites opérationnelles claires tout en tirant parti de la stratégie GSIs pour répondre efficacement à tous les modèles d'accès.

L'approche de conception utilise des principes axés sur les agrégats, regroupant les données en fonction des modèles d'accès plutôt que des limites d'entités rigides. Les principales décisions de conception incluent l'utilisation de tables distinctes pour les entités présentant une faible corrélation d'accès, l'intégration des données associées lorsqu'elles sont toujours consultées ensemble et l'utilisation de collections d'articles pour identifier les relations.

Les tables suivantes et les index qui les accompagnent prennent en charge le schéma de saisie des ordres relationnels :

## Design de table pour employés
<a name="employee-table-design"></a>

La table Employee stocke les informations sur les employés sous la forme d'une seule entité par élément, optimisée pour les recherches directes avec les employés et prenant en charge plusieurs modèles de requêtes grâce à la stratégie GSIs. Ce tableau illustre le principe de conception de tables distinctes pour les entités présentant des caractéristiques opérationnelles indépendantes et une faible corrélation d'accès entre entités.

La table utilise une clé de partition simple (employee\$1id) sans clé de tri, car chaque employé est une entité distincte. Quatre GSIs permettent d'effectuer des requêtes efficaces à l'aide de différents attributs :
+ *EmployeeByName GSI* - Utilise la projection INCLUDE avec tous les attributs des employés pour permettre la récupération complète des informations sur les employés par nom, en gérant les doublons potentiels avec employee\$1id comme clé de tri
+ *EmployeeByWarehouse GSI* - Utilise la projection INCLUDE avec uniquement les attributs essentiels (name, job\$1title, hire\$1date) pour minimiser les coûts de stockage tout en prenant en charge les requêtes basées sur l'entrepôt
+ *EmployeeByJobTitle GSI* - Permet les requêtes basées sur les rôles avec la projection INCLUDE pour le reporting et l'analyse organisationnelle
+ *EmployeeByHireDate GSI* - Utilise une valeur de clé de partition statique « EMPLOYEE » avec hire\$1date comme clé de tri pour permettre des requêtes de plage de dates efficaces pour les recrutements récents. Étant donné que additions/updates les employés ont généralement moins de 1 000 unités WCU, une seule partition peut gérer la charge d'écriture sans problèmes de partition chaude


**Table des employés - Structure de la table de base**  

| employee\$1id (PK) | name | numéro\$1téléphone | identifiant\$1entrepôt | job\$1title | date d'embauche | type\$1entité | 
| --- | --- | --- | --- | --- | --- | --- | 
| emp\$1001 | John Smith | [« \$11-555-0101 »] | wh\$1sea | Responsable | 15/03/2024 | EMPLOYÉ | 
| emp\$1002 | Jane Doe | [« \$11-555-0102 », « \$11-555-0103 »] | wh\$1sea | Associé | 10-01-2025 | EMPLOYÉ | 
| emp\$1003 | Bob Wilson | [« \$11-555-0104"] | wh\$1pdx | Associé | 20/06/2025 | EMPLOYÉ | 
| emp\$1004 | Alice Brown | [« \$11-555-0105 »] | wh\$1pdx | Superviseur | 05/11/2023 | EMPLOYÉ | 
| emp\$1005 | Charlie Davis | [« \$11-555-0106"] | wh\$1sea | Associé | 01/12/2025 | EMPLOYÉ | 


**EmployeeByName GSI - Prise en charge des requêtes relatives aux noms des employés**  

| nom (GSI-PK) | identifiant d'employé (GSI-SK) | numéro\$1téléphone | identifiant\$1entrepôt | job\$1title | date d'embauche | 
| --- | --- | --- | --- | --- | --- | 
| Alice Brown | emp\$1004 | [« \$11-555-0105 »] | wh\$1pdx | Superviseur | 05/11/2023 | 
| Bob Wilson | emp\$1003 | [« \$11-555-0104"] | wh\$1pdx | Associé | 20/06/2025 | 
| Charlie Davis | emp\$1005 | [« \$11-555-0106"] | wh\$1sea | Associé | 01/12/2025 | 
| Jane Doe | emp\$1002 | [« \$11-555-0102 », « \$11-555-0103 »] | wh\$1sea | Associé | 10-01-2025 | 
| John Smith | emp\$1001 | [« \$11-555-0101 »] | wh\$1sea | Responsable | 15/03/2024 | 


**EmployeeByWarehouse GSI - Prise en charge des requêtes relatives aux entrepôts**  

| identifiant d'entrepôt (GSI-PK) | identifiant d'employé (GSI-SK) | name | job\$1title | date d'embauche | 
| --- | --- | --- | --- | --- | 
| wh\$1pdx | emp\$1003 | Bob Wilson | Associé | 20/06/2025 | 
| wh\$1pdx | emp\$1004 | Alice Brown | Superviseur | 05/11/2023 | 
| wh\$1sea | emp\$1001 | John Smith | Responsable | 15/03/2024 | 
| wh\$1sea | emp\$1002 | Jane Doe | Associé | 10-01-2025 | 
| wh\$1sea | emp\$1005 | Charlie Davis | Associé | 01/12/2025 | 


**EmployeeByJobTitle GSI - Prise en charge des requêtes relatives aux titres de poste**  

| title du poste (GSI-PK) | identifiant d'employé (GSI-SK) | name | identifiant\$1entrepôt | date d'embauche | 
| --- | --- | --- | --- | --- | 
| Associé | emp\$1002 | Jane Doe | wh\$1sea | 10-01-2025 | 
| Associé | emp\$1003 | Bob Wilson | wh\$1pdx | 20/06/2025 | 
| Associé | emp\$1005 | Charlie Davis | wh\$1sea | 01/12/2025 | 
| Responsable | emp\$1001 | John Smith | wh\$1sea | 15/03/2024 | 
| Superviseur | emp\$1004 | Alice Brown | wh\$1pdx | 05/11/2023 | 


**EmployeeByHireDate GSI - Prise en charge des demandes d'embauche récentes**  

| type\$1entité (GSI-PK) | hire\$1date (GSI-SK) | employee\$1id | name | identifiant\$1entrepôt | 
| --- | --- | --- | --- | --- | 
| EMPLOYÉ | 05/11/2023 | emp\$1004 | Alice Brown | wh\$1pdx | 
| EMPLOYÉ | 15/03/2024 | emp\$1001 | John Smith | wh\$1sea | 
| EMPLOYÉ | 10-01-2025 | emp\$1002 | Jane Doe | wh\$1sea | 
| EMPLOYÉ | 20/06/2025 | emp\$1003 | Bob Wilson | wh\$1pdx | 
| EMPLOYÉ | 01/12/2025 | emp\$1005 | Charlie Davis | wh\$1sea | 

## Conception de la table client
<a name="customer-table-design"></a>

La table Customer conserve les informations sur les clients grâce à la dénormalisation stratégique de account\$1rep\$1id afin de permettre des requêtes efficaces aux représentants du compte. Ce choix de conception permet de substituer une légère charge de stockage aux performances des requêtes, éliminant ainsi le besoin de joindre les données du client et du représentant du compte.

Le tableau prend en charge plusieurs numéros de téléphone par client à l'aide d'un attribut de liste, ce qui démontre la flexibilité du schéma de DynamoDB. Le GSI unique permet des flux de travail représentatifs des comptes :
+ *CustomerByAccountRep GSI* - Utilise la projection INCLUDE avec des attributs de nom et d'e-mail pour faciliter la gestion des clients par le représentant commercial sans avoir à récupérer l'intégralité des dossiers clients


**Table client - Structure de la table de base**  

| customer\$1id (PK) | name | numéro\$1téléphone | e-mail | account\$1rep\$1id | 
| --- | --- | --- | --- | --- | 
| cust\$1001 | Acme Corporation | [« \$11-555-1001"] | contact@acme.com | rep\$1001 | 
| cust\$1002 | TechStart Inc | [« \$11-555-1002", « \$11-555-1003"] | info@techstart.com | rep\$1001 | 
| cust\$1003 | Négociants mondiaux | [« \$11-555-1004"] | sales@globaltraders.com | rep\$1002 | 
| cust\$1004 | BuildRight SARL | [« \$11-555-1005"] | orders@buildright.com | rep\$1002 | 
| cust\$1005 | FastShip Co | [« \$11-555-1006 »] | support@fastship.com | rep\$1003 | 


**CustomerByAccountRep GSI - Assistance aux demandes des représentants commerciaux**  

| account\$1rep\$1id (GSI-PK) | identifiant\$1client (GSI-SK) | name | e-mail | 
| --- | --- | --- | --- | 
| rep\$1001 | cust\$1001 | Acme Corporation | contact@acme.com | 
| rep\$1001 | cust\$1002 | TechStart Inc | info@techstart.com | 
| rep\$1002 | cust\$1003 | Négociants mondiaux | sales@globaltraders.com | 
| rep\$1002 | cust\$1004 | BuildRight SARL | orders@buildright.com | 
| rep\$1003 | cust\$1005 | FastShip Co | support@fastship.com | 

## Conception de la table de commande
<a name="order-table-design"></a>

Le tableau des commandes utilise le partitionnement vertical avec des éléments distincts pour les en-têtes de commande et les articles de commande. Cette conception permet des requêtes efficaces basées sur les produits tout en conservant tous les composants de la commande dans la même partition pour un accès efficace. Chaque commande est composée de plusieurs articles :
+ *En-tête de commande* - Contient les métadonnées de commande avec PK=ORDER\$1ID, SK=ORDER\$1ID
+ *Articles de commande - Articles* individuels avec PK=ORDER\$1ID, SK=product\$1ID, permettant de poser des questions directes sur les produits

**Note**  
Cette approche de partitionnement vertical allie la simplicité des éléments de commande intégrés à une flexibilité accrue des requêtes. Chaque article de commande devient un article DynamoDB distinct, ce qui permet d'effectuer des requêtes efficaces basées sur les produits tout en conservant toutes les données de commande dans la même partition pour une extraction efficace en une seule demande.

Le tableau inclut une dénormalisation stratégique de account\$1rep\$1id (reproduit à partir de la table Customer) afin de permettre aux représentants du compte de poser des requêtes directes sans avoir à consulter les clients. Pour les scénarios d'écriture à haut débit, les commandes OPEN incluent le statut et les attributs de partition pour permettre le partitionnement des écritures sur plusieurs partitions.

Quatre GSIs prennent en charge différents modèles de requêtes avec des projections optimisées :
+ *OrderByCustomerDate GSI* - Utilise la projection INCLUDE avec le résumé des commandes et les détails des articles pour étayer l'historique des commandes des clients grâce au filtrage par plage de dates
+ *OpenOrdersByDate GSI (Sparse, Sharded)* : utilise une clé de partition à attributs multiples (status \$1 shard) avec 5 partitions pour distribuer 5 000 WPS (écritures par seconde) entre les partitions (1 000 WPS chacune, correspondant à la limite de 1 000 WCU par partition de DynamoDB). Indexe uniquement les commandes OUVERTES (20 % du total), ce qui peut contribuer à réduire les coûts de stockage de GSI. Nécessite des requêtes parallèles sur les 5 partitions avec fusion des résultats côté client
+ *OrderByAccountRep GSI* - Utilise la projection INCLUDE avec les attributs récapitulatifs des commandes pour prendre en charge les flux de travail des représentants des comptes sans les détails complets des commandes
+ *ProductInOrders GSI* - Créé à partir d' OrderItem enregistrements (PK=ORDER\$1ID, SK=product\$1ID), ce GSI permet de rechercher toutes les commandes contenant un produit spécifique. Utilise la projection INCLUDE avec le contexte de commande (customer\$1id, order\$1date, quantity) pour l'analyse de la demande de produits


**Tableau des commandes - Structure de la table de base (partitionnement vertical)**  

| PK | SK | customer\$1id | date\$1commande | status | account\$1rep\$1id | quantity | prix | partition | 
| --- | --- | --- | --- | --- | --- | --- | --- | --- | 
| ord\$1001 | ord\$1001 | cust\$1001 | 15/11/2025 | CLOSED | rep\$1001 |  |  |  | 
| ord\$1001 | prod\$1100 |  |  |  |  | 5 | 25,00 |  | 
| ord\$1002 | ord\$1002 | cust\$1001 | 20-12-2025 | OPEN | rep\$1001 |  |  | 0 | 
| ord\$1002 | prod\$1101 |  |  |  |  | 10 | 15,00 |  | 
| ord\$1003 | ord\$1003 | cust\$1002 | 05/01/2021 | OPEN | rep\$1001 |  |  | 2 | 
| ord\$1003 | prod\$1100 |  |  |  |  | 3 | 25,00 |  | 


**OrderByCustomerDate GSI - Prise en charge des demandes de commande des clients**  

| identifiant\$1client (GSI-PK) | date\$1commande (GSI-SK) | ID de commande | status | total\$1amount | articles de commande | partition | 
| --- | --- | --- | --- | --- | --- | --- | 
| cust\$1001 | 15/11/2025 | ord\$1001 | CLOSED | 225,00 | [\$1product\$1id : « prod\$1100", quantité : 5\$1] |  | 
| cust\$1001 | 20-12-2025 | ord\$1002 | OPEN | 150,00 | [\$1product\$1id : « prod\$1101", quantité : 10\$1] | 0 | 
| cust\$1002 | 05/01/2021 | ord\$1003 | OPEN | 175,00 | [\$1product\$1id : « prod\$1100", quantité : 3\$1] | 2 | 
| cust\$1003 | 10/10/2025 | ord\$1004 | CLOSED | 250,00 | [\$1product\$1id : « prod\$1101", quantité : 5\$1] |  | 
| cust\$1004 | 03/01/2026/ | ord\$1005 | OPEN | 200,00 | [\$1product\$1id : « prod\$1100", quantité : 20\$1] | 1 | 


**OpenOrdersByDate GSI (Sparse, Sharded) : prise en charge des requêtes d'ordre ouvert à haut débit**  

| état (GSI-PK-1) | fragment (GSI-PK-2) | order\$1date (SK) | ID de commande | customer\$1id | account\$1rep\$1id | articles de commande | total\$1amount | 
| --- | --- | --- | --- | --- | --- | --- | --- | 
| OPEN | 0 | 20-12-2025 | ord\$1002 | cust\$1001 | rep\$1001 | [\$1product\$1id : « prod\$1101", quantité : 10\$1] | 150,00 | 
| OPEN | 1 | 03/01/2026/ | ord\$1005 | cust\$1004 | rep\$1002 | [\$1product\$1id : « prod\$1100", quantité : 20\$1] | 200,00 | 
| OPEN | 2 | 05/01/2021 | ord\$1003 | cust\$1002 | rep\$1001 | [\$1product\$1id : « prod\$1100", quantité : 3\$1] | 175,00 | 


**OrderByAccountRep GSI - Prise en charge des demandes des représentants des comptes**  

| account\$1rep\$1id (GSI-PK) | date\$1commande (GSI-SK) | ID de commande | customer\$1id | status | total\$1amount | 
| --- | --- | --- | --- | --- | --- | 
| rep\$1001 | 15/11/2025 | ord\$1001 | cust\$1001 | CLOSED | 225,00 | 
| rep\$1001 | 20-12-2025 | ord\$1002 | cust\$1001 | OPEN | 150,00 | 
| rep\$1001 | 05/01/2021 | ord\$1003 | cust\$1002 | OPEN | 175,00 | 
| rep\$1002 | 10/10/2025 | ord\$1004 | cust\$1003 | CLOSED | 250,00 | 
| rep\$1002 | 03/01/2026/ | ord\$1005 | cust\$1004 | OPEN | 200,00 | 


**ProductInOrders GSI - Prise en charge des demandes de commande de produits**  

| identifiant du produit (GSI-PK) | ID de commande (GSI-SK) | customer\$1id | date\$1commande | quantity | 
| --- | --- | --- | --- | --- | 
| prod\$1100 | ord\$1001 | cust\$1001 | 15/11/2025 | 5 | 
| prod\$1100 | ord\$1003 | cust\$1002 | 05/01/2021 | 3 | 
| prod\$1101 | ord\$1002 | cust\$1001 | 20-12-2025 | 10 | 

## Conception de la table des produits
<a name="product-table-design"></a>

La table Product utilise le modèle de collecte d'articles pour stocker à la fois les métadonnées du produit et les données d'inventaire dans la même partition. Cette conception tire parti de la relation d'identification entre les produits et le stock : l'inventaire ne peut exister sans un produit parent. L'utilisation de PK=Product\$1ID avec SK=Product\$1ID pour les métadonnées du produit et SK=Warehouse\$1ID pour les articles en stock élimine le besoin d'une table d'inventaire et d'un GSI séparés, réduisant ainsi les coûts d'environ 50 %.

Ce modèle permet des requêtes efficaces à la fois pour l'inventaire individuel de l'entrepôt (GetItem avec clé composite) et pour l'ensemble de l'inventaire de l'entrepôt pour un produit (requête sur la clé de partition). L'attribut total\$1inventory de l'élément de métadonnées du produit fournit une agrégation dénormalisée pour des recherches rapides de l'inventaire total.


**Tableau des produits - Structure de la table de base (modèle de collection d'articles)**  

| product\$1id (PK) | warehouse\$1id (SK) | product\$1name | category | prix\$1unitaire | quantité\$1inventaire | inventaire\$1total | 
| --- | --- | --- | --- | --- | --- | --- | 
| prod\$1100 | prod\$1100 | Widget A | Matériel | 25,00 |  | 500 | 
| prod\$1100 | wh\$1sea |  |  |  | 200 |  | 
| prod\$1100 | wh\$1pdx |  |  |  | 150 |  | 
| prod\$1100 | wh\$1atl |  |  |  | 150 |  | 
| prod\$1101 | prod\$1101 | Gadget B | Électronique | 50,00 |  | 300 | 
| prod\$1101 | wh\$1sea |  |  |  | 100 |  | 
| prod\$1101 | wh\$1pdx |  |  |  | 200 |  | 

Chaque table est conçue avec des index secondaires globaux spécifiques (GSIs) pour prendre en charge efficacement les modèles d'accès requis. La conception utilise des principes axés sur les agrégats avec une dénormalisation stratégique et une indexation éparse pour optimiser à la fois les performances et les coûts.

Les principales optimisations de conception incluent :
+ *GSI clairsemé* : indexe OpenOrdersByDate uniquement les commandes OUVERTES (20 % du total), ce qui peut contribuer à réduire les coûts de stockage du GSI
+ *Modèle de collecte d'articles* - La table des produits stocke l'inventaire en utilisant PK=product\$1ID, SK=Warehouse\$1ID pour éliminer une table d'inventaire séparée
+ *Ordre et OrderItems agrégation* - Intégré en un seul article grâce à une corrélation d'accès de 100 %
+ *Dénormalisation stratégique* : account\$1rep\$1id est dupliqué dans la table des commandes pour des requêtes efficaces

Enfin, vous pouvez réexaminer les modèles d’accès définis précédemment. Le tableau suivant montre comment chaque modèle d'accès est pris en charge efficacement à l'aide de la conception multi-tables avec Strategic GSIs. Chaque modèle utilise des recherches de touches directes ou des requêtes GSI uniques, ce qui permet d'éviter des analyses coûteuses et de fournir des performances constantes à toutes les échelles.


| Nº de série | Modèles d’accès | Conditions de requête | 
| --- | --- | --- | 
|  1  |  Rechercher les détails des employés par ID d’employé  |  Tableau des employés : GetItem (employee\$1id="emp\$1001")  | 
|  2  |  Interroger les détails des employés par nom d’employé  |  EmployeeByName GSI : Requête (name="John Smith »)  | 
|  3  |  Trouver le (s) numéro (s) de téléphone d'un employé  |  Tableau des employés : GetItem (employee\$1id="emp\$1001")  | 
|  4  |  Trouver le (s) numéro (s) de téléphone d'un client  |  Table des clients : GetItem (customer\$1id="cust\$1001")  | 
|  5  |  Obtenez des commandes pour les clients dans un intervalle de dates  |  OrderByCustomerDate GSI : requête (customer\$1id="cust\$1001", order\$1date COMPRISE ENTRE « 2025-01-01" ET « 2025-12-31")  | 
|  6  |  Afficher toutes les commandes ouvertes dans un intervalle de dates  |  OpenOrdersByDate GSI : Interrogez 5 partitions en parallèle avec un PK à attributs multiples (status="open » \$1 shard=0-4), SK=ORDER\$1DATE ENTRE « 2025-01-01 » ET « 2025-12-31 », résultats de fusion  | 
|  7  |  Voir tous les employés embauchés récemment  |  EmployeeByHireDate GSI : Requête (Entity\$1Type="Employé », hire\$1date >= « 2025-01-01")  | 
|  8  |  Trouvez tous les employés de Warehouse  |  EmployeeByWarehouse GSI : Requête (warehouse\$1id="wh\$1sea »)  | 
|  9  |  Obtenez tous les articles en commande pour le produit  |  ProductInOrders GSI : Requête (product\$1id="prod\$1100")  | 
|  10  |  Obtenez des stocks de produits dans tous les entrepôts  |  Tableau des produits : requête (product\$1id="prod\$1100")  | 
|  11  |  Attirez des clients par le biais d'un représentant commercial  |  CustomerByAccountRep GSI : Requête (account\$1rep\$1id="rep\$1001")  | 
|  12  |  Recevez les commandes par le représentant du compte  |  OrderByAccountRep GSI : Requête (account\$1rep\$1id="rep\$1001")  | 
|  13  |  Trouvez des employés avec le titre du poste  |  EmployeeByJobTitle GSI : Requête (job\$1title="Manager »)  | 
|  14  |  Obtenez l'inventaire par produit et par entrepôt  |  Tableau des produits : GetItem (product\$1id="prod\$1100", warehouse\$1id="wh\$1sea »)  | 
|  15  |  Obtenez l'inventaire total des produits  |  Tableau des produits : GetItem (product\$1id="prod\$1100", warehouse\$1id="prod\$1100")  | 