Intermédiaire8 min de lecture

L'attribut Type dans DynamoDB

En SQL, la table d'une ligne est son type — une ligne dans documents est un document. Une table unique DynamoDB mélange toutes les entités sous un même schéma, si bien qu'un item ne porte aucune réponse intégrée à la question « qu'est-ce que c'est ? ».

L'attribut Type remet cette réponse en place : 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 — par exemple EntityType: "Document" — nommant l'entité que cet item représente. Parce qu'une table unique mélange de nombreuses entités sous un même schéma, les items ne portent aucun type intégré. Le Type le rétablit, pour que ton code identifie les lignes, filtre un GSI sur une seule entité et survive aux migrations.

  • Estampille un Type à chaque écriture. Un seul attribut — EntityType: "Document" — sur chaque item, sans exception. Cela coûte quelques octets et te sauvera 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 le filtrage par entité unique sur un . Projette le Type dans un index et tu peux restreindre un index surchargé à un seul type d'entité.
  • C'est ta trappe de secours pour les migrations. Quand tu exportes pour re-modéliser ou déplacer une entité vers sa propre table, le Type est la colonne sur laquelle tu découpes.

Pourquoi une table mixte perd le type

La conception à table unique 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 application SaaS de collaboration documentaire. Une partition d'espace de travail contient l'enregistrement de l'espace, 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 rend les quatre items en une seule lecture facturée. Ton code a maintenant une liste d'items bruts et aucun moyen fiable de dire lequel est un document et lequel est un commentaire — sinon en faisant de la correspondance de chaîne sur le SK, ce qui devient fragile dès que ton format de clé change.

Estampille le Type sur chaque item

La solution est un seul attribut à chaque écriture, nommant 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 dès que 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'Aiguillage par Type

Une seule lecture renvoie trois types d'entités ; l'attribut Type aiguille chaque item vers le bon gestionnaire sans toucher aux clés.

Filtre un GSI jusqu'à une seule entité

Le Type gagne sa place sur les index. Disons que tu ajoutes un GSI indexé 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 à la fois des documents et des commentaires — mais une interface de flux ne veut peut-être que les documents.

Deux façons de le restreindre, et la différence, c'est de l'argent :

ApprocheCe que ça coûteQuand l'utiliser
FilterExpression sur le TypeLit tous les items correspondants, les facture tous, écarte les non-correspondants après lectureLes entités mixtes sont rares dans le résultat ; rapide à livrer
Index épars (GSI1PK écrit uniquement sur l'entité cible)Seule l'entité voulue atterrit dans l'indexUne entité domine ; tu veux zéro gaspillage

En on-demand dans us-east-1, une Query de GSI qui renvoie 100 items mixtes de 2 Ko chacun facture environ 100 RCU en cohérence à terme — et une FilterExpression sur EntityType compte quand même chaque ligne avant d'écarter les commentaires. Un index épars qui n'indexe jamais les commentaires ne facture que les lignes de documents. Modélise les deux formes dans le calculateur de tarifs.

Une FilterExpression s'exécute après la lecture des items et après la consommation de la 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 flux aux documents, la requête porte une condition sur l'attribut Type. Assemble la FilterExpression, les noms et les valeurs avec le générateur 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 ne porte que des documents et sauter complètement le filtre ? Écris GSI1PK uniquement sur les items de type document — un . Les items sans la clé du GSI ne se répliquent jamais dans l'index, si bien que la lecture ne touche que les documents. L'attribut Type est ce qui indique à ton écriture quels items sont éligibles.

Garde la valeur stable et au singulier

Choisis la valeur une bonne fois et traite-la comme un enum. Document, jamais parfois Doc et parfois document — une valeur qui dérive est pire qu'aucune valeur, car tes tests d'égalité passent sur une casse et manquent silencieusement l'autre.

Un seul Type par item. Si un item semble être deux entités, c'est en général un signe de mauvais modèle — cela devrait être deux items, chacun dans sa propre collection ou plage de clé de tri, et non une seule ligne portant deux casquettes.

Le gain à la migration

La raison d'estampiller le Type avant d'en avoir besoin : le re-modelage. Le chemin de re-modelage recommandé est export, transformation, réimport — et AWS documente l'export en masse vers S3 précisément pour 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 retombes dans la rétro-ingénierie des clés sur des millions de lignes.

É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 lors d'un re-modelage. Estampille-le sur chaque écriture dès le premier jour — le rajouter après coup sur une table en production implique un remplissage complet.

À lire aussi : conception à table unique pour le pattern de partition mixte qu'il 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'économise jamais de coût de lecture.

Construis le filtre sur le Type avec le générateur 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