Fortgeschritten5 Min. Lesezeit

Composite Sort Keys in DynamoDB

Ein Composite Primary Key ist ein Partition Key plus ein Sort Key. Der Kniff, der ihn mächtig macht, ist das, was du in den Sort Key packst: Kodiere eine Hierarchie als einen einzigen begrenzten String, und ein einziger Query liest einen ganzen Teilbaum in Sortierreihenfolge — keine Joins, keine Rekursion, kein zweiter Round-Trip.

Wie funktionieren Composite Sort Keys in DynamoDB?

Ein Composite Sort Key packt eine Hierarchie in einen einzigen begrenzten String — root/photos/2026/ —, den DynamoDB in UTF-8-Byte-Reihenfolge speichert. Da das Layout bereits zum Baum passt, liest ein einziger Query mit begins_with(SK, "root/photos/") einen ganzen Teilbaum in Pfadreihenfolge. Keine Joins, keine Rekursion, kein zweiter Round-Trip — nur ein Präfix-Scan über eine zusammenhängende Scheibe.

  • Der Sort Key ist ein sortierbarer String, nicht nur eine ID. Packe einen Pfad hinein — root/photos/2026/ — und DynamoDB speichert die Items der Partition automatisch in UTF-8-Byte-Reihenfolge.
  • Ein Trennzeichen verwandelt Präfix-Treffer in Teilbaum-Lesevorgänge. begins_with(SK, "root/photos/") liefert jeden Nachfahren dieses Ordners in einem Query.
  • Sort Keys unterstützen Bereichsbedingungen, keine beliebigen Filter. Du bekommst begins_with, between, >, < — gestalte den Key so, dass der benötigte Lesevorgang ein Präfix oder ein Bereich ist, kein Scan.
  • Das Trennzeichen ist tragend. Wähle eines, das in keinem Pfadsegment auftauchen kann, sonst kollidieren zwei unverwandte Zweige.

Warum der Sort Key das ganze Spiel ist

Aus SQL kommend würdest du einen Ordnerbaum mit einem parent_id-Self-Join modellieren und ihn rekursiv ablaufen — ein Query pro Ebene. In DynamoDB ist das ein N+1-Footgun gegen einen Key-Value-Store, der keine Joins hat.

DynamoDB speichert jedes Item unter einem Partition Key, sortiert nach seinem Sort Key, bei Strings in UTF-8-Byte-Reihenfolge (AWS: Query Key Conditions). Wenn dein Sort Key also der Pfad ist, passt das physische Layout bereits zum Baum. Ein Lesevorgang wird zu einem Präfix-Scan über eine zusammenhängende Scheibe — kein Graph-Walk.

Das ist die Verschiebung: Der Sort Key ist keine Kennung, die du exakt abgleichst. Er ist eine sortierbare Adresse. Gestalte ihn, und der Query fällt von selbst heraus.

Modelliere einen Dateibaum

Angenommen, du speicherst Dateibäume pro Konto. Ein Laufwerk pro Konto ist die natürliche Partition; der Pfad darin ist der Sort Key.

PKSKnode_typebytes
DRIVE#a91root/folder-
DRIVE#a91root/photos/folder-
DRIVE#a91root/photos/2026/folder-
DRIVE#a91root/photos/2026/beach.jpgfile284910
DRIVE#a91root/photos/2026/sunset.jpgfile512004
DRIVE#a91root/docs/folder-
DRIVE#a91root/docs/taxes.pdffile88210

Zwei eigene Konventionen leisten hier die Arbeit:

  • PK = DRIVE#<account> hält den ganzen Baum eines Kontos in einer einzigen Item Collection, sodass jeder Teilbaum-Lesevorgang ein Single-Partition-Query ist.
  • SK ist der vollständige Pfad mit einem abschließenden / bei Ordnern. Der abschließende Schrägstrich ist Absicht — er sorgt dafür, dass ein Ordner vor seinen eigenen Kindern sortiert wird, und hält root/photos/ von einer gleichrangigen Datei namens root/photos getrennt.

Lies einen Teilbaum in einem Query

Liste alles unter root/photos/ auf — Ordner, Unterordner und Dateien, rekursiv:

Query
KeyConditionExpression = PK = :drive AND begins_with(SK, :prefix)
:drive   = "DRIVE#a91"
:prefix  = "root/photos/"

Das liefert root/photos/, root/photos/2026/, beach.jpg und sunset.jpg — in Pfadreihenfolge, in einem abgerechneten Lesevorgang. Du zahlst nur für die Items in dieser Scheibe, nicht für das ganze Laufwerk.

In DynoTable führst du genau diese begins_with-Abfrage gegen den Pfad-Sort-Key aus und der Ordner samt seinen Nachfahren kommt in Pfadreihenfolge zurück — keine Platzhalter-Syntax, die du von Hand schreiben musst.

Brauchst du die rohe KeyConditionExpression (Namen, Werte und begins_with) für deinen eigenen Code? Baue und kopiere sie im DynamoDB Expression Builder.

Eine begins_with-Abfrage auf dem Pfad-Sort-Key in DynoTable, die einen Ordner und seine Nachfahren in Pfadreihenfolge zurückgibt.
Eine begins_with-Abfrage auf dem Pfad-Sort-Key in DynoTable, die einen Ordner und seine Nachfahren in Pfadreihenfolge zurückgibt.

Liste eine Ebene, nicht den ganzen Teilbaum

begins_with gibt dir den rekursiven Lesevorgang. Für eine nicht-rekursive Verzeichnisauflistung — die unmittelbaren Kinder von root/photos/ und nichts Tieferes — speichere ein depth-Attribut und füge einen Sort-Key-Bereich plus einen Filter hinzu, oder teile den Pfad in einen parent-GSI auf. Die einfachste Variante: Halte ein parent-Attribut (root/photos/) und einen darauf verschlüsselten GSI.

Der Punkt: Ein Sort Key beantwortet Präfix- und Bereichs-Fragen günstig. „Nur direkte Kinder" ist eine andere Frage — modelliere sie explizit, statt zu hoffen, dass eine FilterExpression sie effizient macht. Ein Filter läuft nach dem Lesevorgang, und du zahlst für jedes Item, das er verwirft.

Wähle das Trennzeichen sorgfältig

Das Trennzeichen ist Teil deines Datenvertrags. Zwei Regeln:

  • Es darf niemals innerhalb eines Pfadsegments auftauchen. Wenn Dateinamen / enthalten können, ist / das falsche Trennzeichen — eine Datei namens a/b ist nicht von einem Ordner a zu unterscheiden, der b hält. Wähle ein reserviertes Byte (manche Teams verwenden # oder ein Steuerzeichen) und verbiete es in Segmenten.
  • Achte auf die Sortierreihenfolge an Grenzen. / (0x2F) sortiert vor Ziffern und Buchstaben, was für Baumreihenfolge meist das ist, was du willst. Ändere das Trennzeichen, und du änderst die Reihenfolge — verifiziere es an echten Daten.

Composite Sort Key vs. ein separates Sortier-Attribut

Composite Sort Key (root/photos/2026/x)Reiner ID-Sort-Key + parent-Attribut
Teilbaum-LesevorgangEin begins_with-QueryRekursive Queries (N+1) oder GSI-Walk
ReihenfolgePfadreihenfolge, kostenlosMuss ein explizites Sortier-Attribut hinzufügen
Verschieben / UmbenennenAlle Nachfahren neu schreibenEinen parent-Zeiger aktualisieren
Direkt-Kinder-ListeBraucht depth-Attr oder GSINatürlich (parent = x)

Composite Keys gewinnen, wenn Lesevorgänge teilbaumförmig sind und die Reihenfolge zählt; das Flat-ID-Modell gewinnt, wenn der Baum sich ständig ändert. Die meisten leselastigen Hierarchien — Dateibäume, Kategoriebäume, Org-Charts — neigen zu Composite.

Fallstricke und nächste Schritte

  • Überfülle den Key nicht. Alles, was du kodierst, ist unveränderlich und nur per Präfix indexiert. Attribute, die du per Gleichheit abfragst, gehören in eigene Felder oder einen GSI, nicht in den Sort Key gequetscht.
  • Ein Sort Key kann kein beliebiges WHERE. Nur begins_with, between und Vergleiche. Wenn du nach einer FilterExpression greifst, hast du den Key wahrscheinlich falsch modelliert — siehe Query vs. Scan.
  • Mehr zum Key-Design findest du im Single-Table-Design; für den Fall, dass ein Teilbaum-Lesevorgang einen Index statt der Basistabelle braucht, siehe GSI vs. LSI.

Baue die begins_with-Key-Bedingung mit dem Expression Builder, dann lade DynoTable herunter, um diese Präfix-Abfragen gegen deine eigenen Tabellen auszuführen und einen Teilbaum in Pfadreihenfolge zurückkommen zu sehen.

Aktualisiert