DynamoDB Composite Primary Key
Ein Composite Primary Key sind zwei Attribute: ein Partition Key und ein Sort Key. Der Partition Key entscheidet, wo ein Item lebt; der Sort Key ordnet Items innerhalb dieser Partition.
Aus SQL kommend, denk an ihn weniger als eine eindeutige id-Spalte und mehr als
GROUP BY partition, ORDER BY sort, das in die Tabelle selbst eingebacken ist.
Was ist ein DynamoDB Composite Primary Key?
Ein DynamoDB Composite Primary Key kombiniert zwei Attribute: einen Partition Key und einen Sort Key. Der Partition Key entscheidet, in welcher physischen Partition ein Item lebt; der Sort Key ordnet die Items innerhalb dieser Partition. Zusammen bilden sie die eindeutige Identität des Items und lassen einen einzigen Query einen sortierten Bereich statt eines einzelnen Items zurückgeben.
- Zwei Teile, zwei Aufgaben. Der Partition Key leitet das Item auf eine physische Partition; der Sort Key ordnet jedes Item, das diesen Partition Key teilt.
- Eindeutigkeit ist das Paar. Zwei Items können einen Partition-Key-Wert teilen, solange sich ihre Sort Keys unterscheiden — so hält eine Partition viele Zeilen.
- Der Sort Key ist der ganze Sinn. Er ist es, der einen
Queryeinen Bereich (>=,between,begins_with) statt ein einzelnes Item zurückgeben lässt, ohneScan. - Keys müssen Skalare sein. Partition und Sort Keys können nur String, Number oder Binary sein — keine Maps, keine Listen (AWS-Doku).
Einfacher Key vs. Composite Key
Ein Simple Primary Key ist nur ein Partition Key. Er identifiziert ein Item
eindeutig, und du liest es mit GetItem zurück. Das war's — keine
Bereichs-Lesevorgänge, kein „gib mir die neuesten N".
Ein Composite Key fügt den Sort Key hinzu, und diese eine Ergänzung lässt DynamoDB sich wie eine Datenbank anfühlen statt wie eine Hashmap.
| Simple Key | Composite Key | |
|---|---|---|
| Attribute | Nur Partition Key | Partition Key + Sort Key |
| Eindeutigkeit | Partition-Key-Wert | Das Paar der Werte |
| Mehrere Items pro Partition | Nein | Ja |
Query über einen Bereich | Nein (nur GetItem) | Ja (begins_with, between, >) |
| Natürlicher Fit | Lookup per ID | Zeitreihen, One-to-Many, Historie |
Modelliere eine Sensor-Messwert-Tabelle
Angenommen, du sammelst Temperaturproben von einer Flotte von Feldsensoren. Das Zugriffsmuster ist „hol die Messwerte für ein Gerät, neueste zuerst, innerhalb eines Zeitfensters". Das ist ein Lehrbuch-Composite-Key.
Verwende die Geräte-ID als Partition Key und den Messwert-Timestamp als Sort Key:
| deviceId | readingTs | tempC | humidity |
|---|---|---|---|
| DEV#a1b2 | 2026-06-23T08:00:00Z | 21.4 | 48 |
| DEV#a1b2 | 2026-06-23T08:05:00Z | 21.7 | 47 |
| DEV#a1b2 | 2026-06-23T08:10:00Z | 22.1 | 46 |
| DEV#c9d8 | 2026-06-23T08:00:00Z | 19.8 | 55 |
Alle drei DEV#a1b2-Messwerte landen in derselben Partition, physisch zusammen
gespeichert und nach readingTs sortiert.
AWS nennt den Partition Key das Hash-Attribut und den Sort Key das Range-Attribut — der Sort Key ist ein Bereich, innerhalb dessen du scannen kannst (AWS-Doku).
So fallen die Items unter jedem Partition Key in eine Item Collection zusammen:
Ein Query gegen den Partition Key liest jeden Messwert für dieses Gerät, bereits
in Timestamp-Reihenfolge — kein Sortieren auf dem Client, kein zweiter
Round-Trip.
Frage den Bereich ab, scanne ihn nicht
Weil readingTs ein ISO-8601-String ist, sortiert er lexikografisch genauso, wie
er chronologisch sortiert. Ein Zeitfenster-Lesevorgang ist also ein
Key-Condition-Bereich, kein Filter:
Query
deviceId = "DEV#a1b2"
readingTs BETWEEN "2026-06-23T08:00:00Z" AND "2026-06-23T08:10:00Z"
Das ist eine KeyConditionExpression — sie engt den Lesevorgang ein, bevor
DynamoDB Daten zurückgibt, also zahlst du nur für die Items im Fenster. Eine
FilterExpression läuft nach dem Lesevorgang und stellt dir alles in Rechnung,
durch das sie gescannt hat; das ist der Scan-Footgun im
Kleinen.
Der Ausdruck selbst, mit Platzhaltern und typisierten Werten, ist umständlich von
Hand zu schreiben. Baue ihn visuell mit dem
DynamoDB Expression Builder und kopiere die
exakte KeyConditionExpression in deinen SDK-Aufruf.
Gestalte den Sort Key mit Absicht
Der Sort Key ist keine kostenlose Metadaten — er ist der einzige Hebel für Bereichs-Lesevorgänge, also forme ihn nach deinen Queries.
- Verwende einen sortierbaren Timestamp. ISO-8601-Strings oder zero-padded Epoch-Zahlen sortieren korrekt; rohe lokalisierte Daten nicht.
- Präfixiere ihn für One-to-Many-Overloading. Ein Sort Key wie
READING#2026-06-23T08:00:00Zlässt dich Entitätstypen unter einer Partition mischen und sie mitbegins_withzerschneiden. Das ist die Naht ins Single-Table-Design. - Setze die Dimension mit hoher Kardinalität in den Partition Key. Eine
Sensor-ID hat tausende Werte, also verteilt sie Schreibvorgänge gleichmäßig. Ein
Partition Key mit geringer Kardinalität (etwa
region) erzeugt eine Hot Partition.
Wann ein Composite Key dich beißt
Es ist eine Verpflichtung, keine Bequemlichkeit. Die Falle: Du wählst einen Partition Key, gehst live, und entdeckst dann ein Zugriffsmuster, das eine andere Gruppierung braucht — „alle Messwerte über 30 °C über die ganze Flotte".
Die Basistabelle kann das nicht beantworten; der Partition Key ist fest. Deine Optionen sind ein Global Secondary Index mit einem anderen Key oder eine Umstrukturierung.
Zähle deine Lesevorgänge auf, bevor du das Key-Schema festlegst. Einen Primary Key
zu ändern bedeutet eine Tabellenmigration, kein ALTER TABLE.
Nächste Schritte
Composite Keys sind das Fundament unter Item Collections, One-to-Many-Beziehungen und den meisten nützlichen Index-Designs — lies als Nächstes Single-Table-Design und GSI vs. LSI, um zu sehen, wohin sie führen.
Skizziere deine KeyConditionExpression im
DynamoDB Expression Builder, dann
probiere DynoTable aus, um deine echten Partitionen zu durchsuchen und
zu beobachten, wie sich die Sortierreihenfolge gegen deine eigenen Tabellen
einreiht.