Fortgeschritten7 Min. Lesezeit

Das Type-Attribut in DynamoDB

In SQL ist die Tabelle einer Zeile ihr Typ — eine Zeile in documents ist ein Dokument. Eine DynamoDB-Single-Table mischt jede Entität unter einem Schema, also trägt ein Item keine eingebaute Antwort auf die Frage „Was ist das?".

Das Type-Attribut liefert diese Antwort zurück: ein einfacher String auf jedem Item, der die Entität benennt, die es repräsentiert.

Was ist das Type-Attribut in DynamoDB?

Das Type-Attribut ist ein einfacher String, den du auf jedes Item prägst — wie EntityType: "Document" — der die Entität benennt, die dieses Item repräsentiert. Weil eine Single Table viele Entitäten unter einem Schema mischt, tragen Items keinen eingebauten Typ. Der Type liefert ihn zurück, damit dein Code Zeilen identifiziert, einen GSI auf eine Entität filtert und Migrationen übersteht.

  • Präge bei jedem Schreibvorgang einen Type auf. Ein Attribut — EntityType: "Document" — auf jedem Item, ohne Ausnahme. Es kostet ein paar Bytes und erspart dir später viel.
  • Es identifiziert Entitäten in einer gemischten Partition. Eine Query liefert Workspaces, Dokumente und Kommentare zusammen zurück; der Type sagt deinem Code, was was ist, ohne Key-Präfixe zu parsen.
  • Es ermöglicht Single-Entity-Filtering auf einem GSI. Projiziere den Type in einen Index und du kannst einen überladenen Index auf genau einen Entitätstyp einschränken.
  • Es ist dein Notausgang für Migrationen. Wenn du für eine Neumodellierung exportierst oder eine Entität in ihre eigene Tabelle verschiebst, ist der Type die Spalte, an der du aufteilst.

Warum eine gemischte Tabelle den Typ verliert

Single-Table-Design speichert jede Entität in einer Tabelle hinter generischen Keys wie PK und SK. Genau das ist der Sinn — eine Query liefert einen Parent und seine Children zusammen zurück. Aber das bedeutet, eine Partition ist heterogen.

Nimm eine SaaS-App für Dokumentenzusammenarbeit. Eine Workspace-Partition hält den Workspace-Datensatz, seine Dokumente und die Kommentare zu diesen Dokumenten:

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" gibt alle vier Items in einem abgerechneten Read zurück. Jetzt hat dein Code eine Liste roher Items und keine verlässliche Möglichkeit zu sagen, welches ein Dokument und welches ein Kommentar ist — abgesehen vom String-Matching auf dem SK, was brüchig wird, sobald sich dein Key-Format ändert.

Präge den Type auf jedes Item

Die Lösung ist ein Attribut bei jedem Schreibvorgang, das die Entität benennt:

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

Eine Verzweigung über item.EntityType === "Document" ist ein stabiler Gleichheitscheck. SK.startsWith("DOC#") && SK.includes("#CMT#") zu parsen ist eine Vermutung, die bricht, sobald du den Key überarbeitest. Der Type entkoppelt deine Read-Logik von deiner Key-Kodierung — das ist der eigentliche Gewinn.

Query PK = 'WS#acme'Gemischte PartitionEntityType: 'Workspace'EntityType: 'Document'EntityType: 'Comment'Nach Type routen

Ein Read liefert drei Entitätstypen zurück; das Type-Attribut routet jedes Item zum richtigen Handler, ohne die Keys anzufassen.

Einen GSI auf eine Entität filtern

Der Type verdient sich seinen Platz bei Indizes. Sagen wir, du fügst einen GSI mit GSI1PK = WS#acme, GSI1SK = updatedAt hinzu, um „alles kürzlich Geänderte in diesem Workspace, neuestes zuerst" aufzulisten. Ein überladener Index zieht Dokumente und Kommentare herein — aber eine Feed-UI will vielleicht nur Dokumente.

Zwei Wege, ihn einzuschränken, und der Unterschied ist Geld:

AnsatzWas es kostetWann verwenden
FilterExpression auf TypeLiest alle passenden Items, berechnet alle, verwirft Nicht-Treffer nach dem ReadGemischte Entitäten sind im Ergebnis selten; schnell fertig
Sparse Index (Type im GSI1PK)Nur die gewünschte Entität landet überhaupt im IndexEine Entität dominiert; du willst null Verschwendung

Eine FilterExpression läuft nachdem Items gelesen wurden und nachdem Kapazität verbraucht wurde — AWS sagt ausdrücklich, dass Filtern die Read-Kosten nicht senkt (DynamoDB Developer Guide: FilterExpression). Auf Type zu filtern ist ehrlich, nicht kostenlos: Du zahlst für die Kommentare, die du wegwirfst.

Um den Feed auf Dokumente einzuschränken, trägt die Query eine Bedingung auf dem Type-Attribut. Stelle die FilterExpression, Names und Values mit dem DynamoDB Expression Builder zusammen — er gibt den Platzhalter #t = :doc aus, damit du dich nicht an einem reservierten Wort vertippst.

KeyConditionExpression     GSI1PK = :ws
FilterExpression           #t = :doc
ExpressionAttributeNames   { "#t": "EntityType" }
ExpressionAttributeValues  { ":ws": "WS#acme", ":doc": "Document" }

Willst du, dass der Index nur Dokumente führt und den Filter ganz überspringt? Schreibe GSI1PK nur auf Dokument-Items — ein Sparse Index. Items ohne den GSI-Key replizieren nie in den Index, sodass der Read allein Dokumente berührt. Das Type-Attribut ist das, was deinem Writer sagt, welche Items qualifizieren.

Halte den Wert stabil und singulär

Wähle den Wert einmal und behandle ihn als Enum. Document, nie mal Doc und mal document — ein driftender Wert ist schlimmer als kein Wert, denn deine Gleichheitschecks bestehen bei einer Schreibweise und verfehlen die andere still.

Ein Type pro Item. Wenn sich ein Item wie zwei Entitäten anfühlt, ist das meist ein Modellierungsgeruch — es sollten zwei Items sein, jedes in seiner eigenen Collection oder seinem eigenen Sort-Key-Bereich, nicht eine Zeile mit zwei Hüten.

Der Migrations-Payoff

Der Grund, den Type aufzuprägen, bevor du ihn brauchst: Neumodellierung. Der empfohlene Pfad zur Neumodellierung ist exportieren, transformieren, reimportieren — und AWS dokumentiert Bulk-Export nach S3 für genau diese Art von Offline-Umformung (DynamoDB nach S3 exportieren).

Wenn dieser Tag kommt, ist der Type die Spalte, nach der du GROUP BY gruppierst. Willst du Kommentare in ihre eigene Tabelle heben oder den Export in Entitäts-Dateien für ein Analytics-Warehouse renormalisieren? Du teilst den Dump an EntityType auf. Ohne ihn bist du wieder beim Reverse-Engineering von Keys über Millionen von Zeilen.

Nächste Schritte

Das Type-Attribut ist eine günstige Versicherung: Entitäten in einem gemischten Read identifizieren, einen überladenen GSI filtern und sauber aufteilen, wenn du neu modellierst. Präge es vom ersten Tag an bei jedem Schreibvorgang auf — nachträglich auf eine Live-Tabelle aufzubringen bedeutet ein vollständiges Backfill.

Verwandte Lektüre: Single-Table-Design für das Gemischte-Partition-Muster, dem dies dient, GSI vs LSI für die Wahl der Index-Form hinter einem Sparse Index und Query vs Scan dafür, warum eine FilterExpression dir nie Read-Kosten spart.

Baue den Filter auf dem Type mit dem DynamoDB Expression Builder, und probiere DynoTable aus, um eine echte Tabelle mit gemischten Entitäten zu durchsuchen und zu sehen, wie sich die Type-Spalte über jedes Item ausrichtet.

Aktualisiert