L'attribut Type dans DynamoDB
En SQL, la table d'un enregistrement est son type — un enregistrement dans
documents est un document. Une table unique DynamoDB mélange toutes les entités
sous un seul schéma, donc un item ne porte aucune réponse intégrée à la question
« qu'est-ce que c'est ? ».
L'attribut Type rétablit cette réponse : une simple chaîne sur chaque item qui nomme l'entité qu'il représente.
Qu'est-ce que l'attribut Type dans DynamoDB ?
L'attribut Type est une simple chaîne que tu estampilles sur chaque item — comme EntityType: "Document" — qui nomme l'entité que cet item représente. Parce qu'une table unique mélange de nombreuses entités sous un seul schéma, les items ne portent aucun type intégré. Le Type le rétablit, afin que ton code identifie les enregistrements, filtre un GSI sur une seule entité et survive aux migrations.
- Estampille un Type à chaque écriture. Un attribut —
EntityType: "Document"— sur chaque item, sans exception. Il coûte quelques octets et te sauve plus tard. - Il identifie les entités dans une partition mixte. Un
Queryrenvoie des espaces de travail, des documents et des commentaires ensemble ; le Type indique à ton code lequel est lequel sans analyser les préfixes de clé. - Il permet de filtrer sur une seule entité dans un GSI. Projette le Type dans un index et tu peux restreindre un index surchargé à exactement un type d'entité.
- C'est ta porte de secours pour les migrations. Quand tu exportes pour remodéliser ou déplacer une entité dans sa propre table, le Type est la colonne sur laquelle tu découpes.
Pourquoi une table mixte perd le type
Le single-table design stocke chaque entité dans
une seule table derrière des clés génériques comme PK et SK. C'est tout
l'intérêt — un seul Query renvoie un parent et ses enfants ensemble. Mais cela
signifie qu'une partition est hétérogène.
Prenons une appli SaaS de collaboration documentaire. Une partition d'espace de travail contient l'enregistrement de l'espace de travail, ses documents et les commentaires sur ces documents :
| PK | SK | attributes |
|---|---|---|
| WS#acme | META | name, plan, seats |
| WS#acme | DOC#a1#META | title, owner, wordCount |
| WS#acme | DOC#a1#CMT#0007 | author, body, createdAt |
| WS#acme | DOC#a1#CMT#0008 | author, body, createdAt |
Query PK = "WS#acme" te renvoie les quatre items en une seule lecture facturée.
Maintenant ton code a une liste d'items bruts et aucun moyen fiable de dire lequel
est un document et lequel est un commentaire — sinon faire du string-matching sur
le SK, ce qui est fragile dès que ton format de clé change.
Estampille le Type sur chaque item
La solution est un attribut sur chaque écriture, qui nomme l'entité :
| PK | SK | EntityType | title |
|---|---|---|---|
| WS#acme | META | Workspace | — |
| WS#acme | DOC#a1#META | Document | Q3 Roadmap |
| WS#acme | DOC#a1#CMT#0007 | Comment | — |
Brancher sur item.EntityType === "Document" est un test d'égalité stable.
Analyser SK.startsWith("DOC#") && SK.includes("#CMT#") est une supposition qui
casse quand tu fais évoluer la clé. Le Type découple ta logique de lecture de ton
encodage de clé — c'est le vrai gain.
Une lecture renvoie trois types d'entité ; l'attribut Type achemine chaque item vers le bon gestionnaire sans toucher aux clés.
Filtrer un GSI sur une seule entité
Le Type prouve sa valeur sur les index. Disons que tu ajoutes un GSI clé sur
GSI1PK = WS#acme, GSI1SK = updatedAt pour lister « tout ce qui a récemment
changé dans cet espace de travail, du plus récent au plus ancien ». Un index
surchargé ramasse des documents et des commentaires — mais une UI de fil
d'actualité peut ne vouloir que des documents.
Deux façons de le restreindre, et la différence se chiffre en argent :
| Approche | Ce que ça coûte | Quand l'utiliser |
|---|---|---|
FilterExpression sur le Type | Lit tous les items correspondants, les facture tous, écarte les non-correspondances après lecture | Les entités mixtes sont rares dans le résultat ; rapide à livrer |
Index épars (Type dans GSI1PK) | Seule l'entité que tu veux atterrit dans l'index | Une entité domine ; tu veux zéro gaspillage |
Une FilterExpression s'exécute après la lecture des items et après la
consommation de capacité — AWS est explicite : le filtrage ne réduit pas le coût
de lecture
(DynamoDB Developer Guide : FilterExpression).
Filtrer sur le Type est honnête, pas gratuit : tu paies pour les commentaires que
tu jettes.
Pour restreindre le fil aux documents, la requête porte une condition sur
l'attribut Type. Assemble la FilterExpression, les noms et les valeurs avec le
constructeur d'expressions DynamoDB — il
émet le placeholder #t = :doc pour que tu ne te trompes pas sur un mot réservé.
KeyConditionExpression GSI1PK = :ws
FilterExpression #t = :doc
ExpressionAttributeNames { "#t": "EntityType" }
ExpressionAttributeValues { ":ws": "WS#acme", ":doc": "Document" }
Tu veux que l'index porte uniquement des documents et sauter complètement le
filtre ? Écris GSI1PK seulement sur les items de type document — un index
épars. Les items sans la clé GSI ne se répliquent jamais dans l'index, donc la
lecture ne touche que les documents. L'attribut Type est ce qui indique à ton
écrivain quels items sont éligibles.
Garde la valeur stable et singulière
Choisis la valeur une fois et traite-la comme un enum. Document, jamais parfois
Doc et parfois document — une valeur qui dérive est pire que pas de valeur,
car tes tests d'égalité passent sur une casse et manquent silencieusement l'autre.
Un Type par item. Si un item semble être deux entités, c'est généralement une mauvaise odeur de modélisation — il devrait s'agir de deux items, chacun dans sa propre collection ou plage de clés de tri, pas un enregistrement portant deux casquettes.
Le bénéfice en migration
La raison d'estampiller le Type avant d'en avoir besoin : le remodelage. Le chemin de remodelage recommandé est exporter, transformer, réimporter — et AWS documente l'export en masse vers S3 pour exactement ce genre de remise en forme hors ligne (Exporter DynamoDB vers S3).
Le jour venu, le Type est la colonne sur laquelle tu fais GROUP BY. Tu veux
extraire les commentaires dans leur propre table, ou renormaliser l'export en
fichiers par entité pour un entrepôt analytique ? Tu découpes le dump sur
EntityType. Sans lui, tu reviens à faire de la rétro-ingénierie sur les clés à
travers des millions d'enregistrements.
Étapes suivantes
L'attribut Type est une assurance bon marché : identifier les entités dans une lecture mixte, filtrer un GSI surchargé et découper proprement quand tu remodélises. Estampille-le sur chaque écriture dès le premier jour — l'ajouter après coup sur une table en production impose un backfill complet.
Lectures liées : single-table design pour le
pattern de partition mixte que ceci sert, GSI vs LSI pour
choisir la forme d'index derrière un index épars, et
Query vs Scan pour comprendre pourquoi une
FilterExpression ne t'épargne jamais le coût de lecture.
Construis le filtre sur le Type avec le constructeur d'expressions DynamoDB, et essaie DynoTable pour parcourir une vraie table multi-entités et voir la colonne Type s'aligner sur chaque item.