Intermédiaire6 min de lecture

Trier DynamoDB sur un attribut changeant (mutable)

Tu modélises une clé de tri autour d'un attribut pour pouvoir interroger les items dans son ordre — puis l'attribut change. Le statut d'un ticket, l'état d'une commande, la priorité d'une tâche. Voici le piège que te tend DynamoDB : tu ne peux pas mettre à jour un attribut de clé sur place. Une clé primaire est immuable pour toute la vie de l'item. Change une valeur qui fait partie de la clé et tu n'édites pas un item — tu le déplaces, ce que DynamoDB t'oblige à faire explicitement.

Peut-on modifier une clé de tri DynamoDB ?

Non. La clé de tri fait partie de la clé primaire, et les attributs de clé DynamoDB sont immuables — UpdateItem ne peut pas modifier la valeur d'une clé de partition ou de tri, et il n'existe aucune opération « déplacer un item ». Pour la changer, il faut supprimer l'ancien item et en écrire un nouveau, ou conserver la valeur volatile sur une clé de tri de GSI à la place.

  • Les attributs de clé sont immuables. Tu ne peux pas faire un UpdateItem sur la valeur d'une clé de partition ou de tri — DynamoDB n'a aucune opération « déplacer un item ».
  • Pour changer une valeur de clé, tu supprimes l'ancien item et tu en mets un nouveau — idéalement dans une transaction pour que ce soit atomique.
  • Mieux : garde la valeur volatile hors de la clé de la table de base et mets-la plutôt sur une clé de tri de GSI — les clés de GSI peuvent changer, car mettre à jour l'item de base re-propage simplement l'entrée d'index.
  • Choisis des clés de tri qui ne changent pas (horodatages, ids immuables) chaque fois que le pattern d'accès le permet.

Le problème : un statut sur lequel tu veux trier, et qui n'arrête pas de changer

Disons que tu gères un service de support et que tu veux lister les tickets d'une équipe triés par statut, donc tu mets le statut dans la clé de tri :

PK: TEAM#7   SK: STATUS#open#TICKET#8842

Maintenant le ticket passe à pending. Tu aimerais juste faire un UpdateItem de la clé de tri vers STATUS#pending#TICKET#8842 — mais DynamoDB rejette toute écriture qui change un attribut de clé. La clé est l'adresse de l'item ; tu ne peux pas éditer l'adresse sur place. Le statut que tu as choisi pour trier est précisément ce qui ne veut pas rester en place.

Option 1 : supprimer et recréer (de façon atomique)

Si la valeur doit vivre dans la clé de la table de base, la changer signifie supprimer l'ancien item et écrire le nouveau :

1. DeleteItem  PK=TEAM#7  SK=STATUS#open#TICKET#8842
2. PutItem     PK=TEAM#7  SK=STATUS#pending#TICKET#8842  (mêmes attributs)

Fais-le dans un TransactWriteItems pour que le delete et le put réussissent tous les deux ou échouent tous les deux — sinon un crash entre les deux perd le ticket ou le duplique. Ça marche, mais chaque changement de statut devient maintenant deux écritures plus une transaction ; bien pour des changements occasionnels, coûteux pour des changements fréquents.

Option 2 : garder la valeur mutable hors de la clé de base (préféré)

Le design le plus propre : fais de la clé de la table de base quelque chose d'immuable (l'id du ticket) et mets la valeur volatile et triable sur une clé de tri de GSI.

Base:  PK: TICKET#8842   status: "open"   teamId: TEAM#7
GSI:   GSI1PK: TEAM#7    GSI1SK: STATUS#open#TICKET#8842

Maintenant changer le statut est un simple UpdateItem sur l'attribut status de l'item de base — ce que DynamoDB autorise, car status n'est pas une clé de la table de base. DynamoDB re-propage alors l'entrée du GSI automatiquement vers sa nouvelle position triée. Une écriture, pas de transaction, pas de danse supprimer-recréer.

OuiNon, c'est une clé de tri de GSILe statut passe de open àpendingLa valeur est-elle dans une clé dela table de base ?Supprimer + recréer dans unetransactionSimple UpdateItem ; le GSI sere-propage

Le compromis : le GSI est à cohérence à terme et coûte du stockage/des écritures en plus — mais pour une valeur qui change souvent, c'est bien moins cher que supprimer-recréer à chaque changement.

Concevoir les clés dans DynoTable

Construis et prévisualise les conditions de clé pour la lecture de base et la lecture du GSI dans le constructeur d'expressions DynamoDB.

Dans DynoTable, tu choisis ensuite par quel index passe une requête et tu regardes la valeur volatile se trier sur le GSI tandis que l'item de base conserve sa clé immuable — les deux lectures côte à côte sur de vraies données.

Interrogation d'un GSI trié par statut tandis que l'item de base garde une clé immuable dans DynoTable.
Interrogation d'un GSI trié par statut tandis que l'item de base garde une clé immuable dans DynoTable.

Pièges et étapes suivantes

  • N'essaie jamais de faire un UpdateItem sur un attribut de clé — c'est rejeté ; les valeurs de clé sont fixes pour la vie de l'item.
  • Si tu dois le déplacer, fais delete+put dans une transaction — jamais comme deux écritures non protégées.
  • Préfère des clés de base immuables + un GSI pour tout attribut sur lequel tu tries et que tu modifies.
  • N'oublie pas la cohérence à terme du GSI — l'entrée re-triée apparaît après un bref délai de propagation.
  • À voir aussi : stratégies de clé de tri, GSI vs LSI, transactions.

Envie de voir comment un attribut mutable se trie sur un GSI par rapport à la table de base ? Télécharge DynoTable et explore tes index directement.

Mis à jour