Débutant8 min de lecture

Clé primaire composite DynamoDB : partition key et sort key expliquées

Une clé primaire composite, c'est deux attributs : une clé de partition et une clé de tri. La clé de partition décide où vit un item ; la clé de tri ordonne les items à l'intérieur de cette partition.

En venant de SQL, pense-y moins comme une colonne id unique et plus comme un GROUP BY partition, ORDER BY sort cuit dans la table elle-même.

Qu'est-ce qu'une clé primaire composite DynamoDB ?

Une clé primaire composite DynamoDB combine deux attributs : une clé de partition et une clé de tri. La clé de partition détermine dans quelle partition physique vit un item ; la clé de tri ordonne les items à l'intérieur de cette partition. Ensemble, elles forment l'identité unique de l'item et permettent à un seul Query de renvoyer une plage triée plutôt qu'un seul item.

  • Deux parties, deux rôles. La clé de partition route l'item vers une partition physique ; la clé de tri ordonne chaque item qui partage cette clé de partition.
  • L'unicité est la paire. Deux items peuvent partager une valeur de clé de partition tant que leurs clés de tri diffèrent — c'est ainsi qu'une partition contient plusieurs lignes.
  • La clé de tri est tout l'intérêt. C'est ce qui permet à un Query de renvoyer une plage (>=, between, begins_with) plutôt qu'un seul item, sans Scan.
  • Les clés doivent être des scalaires. Les clés de partition et de tri ne peuvent être que string, number ou binary — pas de maps, pas de lists (Docs AWS).

Clé simple vs clé composite

Une clé primaire simple n'est qu'une clé de partition. Elle identifie un item de façon unique, et tu le relis avec GetItem. C'est tout — pas de lectures de plage, pas de « donne-moi les N plus récents ».

Une clé composite ajoute la clé de tri, et cet unique ajout est ce qui fait que DynamoDB ressemble à une base de données plutôt qu'à une hash map.

Clé simpleClé composite
AttributsClé de partition seuleClé de partition + clé de tri
UnicitéValeur de clé de partitionLa paire de valeurs
Plusieurs items par partitionNonOui
Query d'une plageNon (GetItem seul)Oui (begins_with, between, >)
Ajustement naturelLookup par idSéries temporelles, un-à-plusieurs, historique

Modéliser une table de relevés de capteurs

Disons que tu collectes des échantillons de température depuis une flotte de capteurs de terrain. Le mode d'accès est « obtenir les relevés d'un appareil, les plus récents d'abord, dans une fenêtre temporelle ». C'est une clé composite manuel.

Utilise l'id de l'appareil comme clé de partition et le timestamp du relevé comme clé de tri :

deviceIdreadingTstempChumidity
DEV#a1b22026-06-23T08:00:00Z21.448
DEV#a1b22026-06-23T08:05:00Z21.747
DEV#a1b22026-06-23T08:10:00Z22.146
DEV#c9d82026-06-23T08:00:00Z19.855

Les trois relevés DEV#a1b2 atterrissent dans la même partition, physiquement stockés ensemble et triés par readingTs.

AWS appelle la clé de partition l'attribut de hash et la clé de tri l'attribut de plage — la clé de tri est une plage que tu peux scanner à l'intérieur (Docs AWS).

Voici comment les items s'effondrent en une seule collection d'items sous chaque clé de partition :

Partition : DEV#a1b2readingTs 08:00readingTs 08:05readingTs 08:10Query deviceId = DEV#a1b2

Un seul Query contre la clé de partition lit chaque relevé de cet appareil, déjà dans l'ordre des timestamps — pas de tri côté client, pas de second aller-retour.

Ce que coûte cette fenêtre

Dix relevés de 2 Ko chacun dans la partition totalisent 20 Ko facturés. DynamoDB arrondit les lectures par bloc de 4 Ko, donc un Query à cohérence à terme sur cette fenêtre coûte 3 unités de requête de lecture (20 Ko → cinq blocs de 4 Ko × 0,5 RCU chacun). Une lecture fortement cohérente sur la même fenêtre coûte 5 unités (une RCU par bloc). Récupère les mêmes dix lignes avec dix GetItem séparés et la règle du minimum-un-bloc s'applique par item → 5 unités à cohérence à terme, 10 fortement cohérentes — avant de compter les allers-retours supplémentaires.

Motif de lectureItemsDonnées touchéesUnités lecture CT
Un Query, readingTs entre début et fin1020 Ko3
10 × GetItem sur la clé composite complète1020 Ko5
Query partition seule, filtre humidité dans l'app1020 Ko3
Scan table, filtre deviceId + fenêtre temporelletoustable entièretaille de table

Passe ReturnConsumedCapacity: TOTAL pendant le prototypage ; le calculateur de tarifs transforme ce compte d'unités en ligne mensuelle une fois que tu connais les requêtes par seconde.

Requête la plage, ne la scanne pas

Parce que readingTs est une chaîne ISO-8601, elle trie lexicographiquement de la même façon qu'elle trie chronologiquement. Donc une lecture par fenêtre temporelle est une plage de condition de clé, pas un filtre :

Query
deviceId  = "DEV#a1b2"
readingTs BETWEEN "2026-06-23T08:00:00Z" AND "2026-06-23T08:10:00Z"

C'est un KeyConditionExpression — il restreint la lecture avant que DynamoDB ne renvoie les données, donc tu paies seulement pour les items de la fenêtre. Une FilterExpression s'exécute après la lecture et te facture pour tout ce qu'elle a scanné ; c'est le footgun du Scan en miniature.

L'expression elle-même, avec les placeholders et les valeurs typées, est fastidieuse à écrire à la main. Construis-la visuellement avec le DynamoDB Expression Builder et copie le KeyConditionExpression exact dans ton appel SDK.

Conçois la clé de tri exprès

La clé de tri n'est pas une métadonnée gratuite — c'est le seul levier pour les lectures de plage, alors façonne-la à tes requêtes.

  • Utilise un timestamp triable. Les chaînes ISO-8601 ou les nombres epoch trient correctement ; les dates localisées brutes non.
  • Préfixe-la pour le un-à-plusieurs. Une clé de tri comme READING#2026-06-23T08:00:00Z te permet de mêler des types d'entités sous une seule partition et de les trancher avec begins_with. C'est la couture vers le single-table design.
  • Mets la dimension à forte cardinalité dans la clé de partition. L'id de capteur a des milliers de valeurs, donc il répartit les écritures équitablement. Une clé de partition à faible cardinalité (disons region) crée une .

Une clé de partition avec seulement cinquante valeurs distinctes sur un flux de 10 000 écritures par seconde concentre ~200 WCU par partition logique avant que DynamoDB ne split — correct à l'échelle prototype, douloureux à l'échelle production. Préfère des identifiants qui grandissent avec ta flotte (id appareil, id tenant, id session) plutôt que des regroupements grossiers, sauf si tu colocalises délibérément un dataset borné.

Quand une clé composite te mord

C'est un engagement, pas une commodité. Le piège : tu choisis une clé de partition, tu livres, puis tu découvres un mode d'accès qui a besoin d'un autre regroupement — « tous les relevés au-dessus de 30 °C dans toute la flotte ».

La table de base ne peut pas répondre à ça ; la clé de partition est fixée. Tes options sont un global secondary index avec une clé différente, ou une restructuration.

Énumère tes lectures avant de committer le schéma de clé. Changer une clé primaire signifie une migration de table, pas un ALTER TABLE.

Dans DynoTable, ouvre le navigateur de table et inspecte une table à clé composite côte à côte avec ses GSI — l'ordre de tri sur la clé de tri est visible ligne par ligne, ce qui rend les formats de timestamp décalés d'un évidents avant qu'ils n'atteignent la production.

Étapes suivantes

Les clés composites sont la fondation sous les collections d'items, les relations un-à-plusieurs et la plupart des conceptions d'index utiles — lis ensuite single-table design et GSI vs LSI pour voir où elles mènent.

Esquisse ton KeyConditionExpression dans le DynamoDB Expression Builder, émets le Query paginé complet dans le query builder, puis essaie DynoTable pour parcourir tes vraies partitions et observer l'ordre de tri s'aligner sur tes propres tables.

Mis à jour