Intermédiaire7 min de lecture

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 Query renvoie 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 :

PKSKattributes
WS#acmeMETAname, plan, seats
WS#acmeDOC#a1#METAtitle, owner, wordCount
WS#acmeDOC#a1#CMT#0007author, body, createdAt
WS#acmeDOC#a1#CMT#0008author, 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é :

PKSKEntityTypetitle
WS#acmeMETAWorkspace
WS#acmeDOC#a1#METADocumentQ3 Roadmap
WS#acmeDOC#a1#CMT#0007Comment

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.

Query PK = 'WS#acme'Partition mixteEntityType: 'Workspace'EntityType: 'Document'EntityType: 'Comment'Router par Type

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 :

ApprocheCe que ça coûteQuand l'utiliser
FilterExpression sur le TypeLit tous les items correspondants, les facture tous, écarte les non-correspondances après lectureLes 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'indexUne 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.

Mis à jour