Fortgeschritten5 Min. Lesezeit

DynamoDB nach einem sich ändernden (mutablen) Attribut sortieren

Du modellierst einen Sort Key um ein Attribut herum, um Items in dessen Reihenfolge abfragen zu können — dann ändert sich das Attribut. Der Status eines Tickets, der Zustand einer Bestellung, die Priorität einer Aufgabe. Hier ist der Haken, den DynamoDB dir hinwirft: du kannst ein Key-Attribut nicht an Ort und Stelle aktualisieren. Ein Primary Key ist für die Lebensdauer des Items unveränderlich. Änderst du einen Wert, der Teil des Key ist, editierst du kein Item — du verschiebst es, und DynamoDB zwingt dich, das explizit zu tun.

Kann man einen DynamoDB Sort Key ändern?

Nein. Ein Sort Key ist Teil des Primary Key, und DynamoDB-Key-Attribute sind unveränderlich — UpdateItem kann einen Partition- oder Sort-Key-Wert nicht bearbeiten, und es gibt keine „Item verschieben"-Operation. Um ihn zu ändern, musst du das alte Item löschen und ein neues anlegen, oder du hältst den volatilen Wert stattdessen auf einem GSI-Sort-Key.

  • Key-Attribute sind unveränderlich. Du kannst einen Partition- oder Sort-Key-Wert nicht per UpdateItem ändern — DynamoDB hat keine „Item verschieben"-Operation.
  • Um einen Key-Wert zu ändern, löschst du das alte Item und legst ein neues an — idealerweise in einer Transaktion, damit es atomar ist.
  • Besser: halte den volatilen Wert außerhalb des Base-Table-Key und lege ihn stattdessen auf einen GSI-Sort-Key — GSI-Keys können sich ändern, weil das Aktualisieren des Base-Items den Index-Eintrag einfach neu propagiert.
  • Wähle Sort Keys, die sich nicht ändern (Timestamps, unveränderliche IDs), wann immer das Access Pattern es zulässt.

Das Problem: ein Status, nach dem du sortieren willst, der sich ständig ändert

Nimm an, du betreibst einen Support-Desk und willst die Tickets eines Teams nach Status geordnet auflisten, also packst du den Status in den Sort Key:

PK: TEAM#7   SK: STATUS#open#TICKET#8842

Jetzt wechselt das Ticket auf pending. Du würdest gern einfach den Sort Key per UpdateItem auf STATUS#pending#TICKET#8842 ändern — aber DynamoDB lehnt jeden Write ab, der ein Key-Attribut ändert. Der Key ist die Adresse des Items; du kannst die Adresse nicht an Ort und Stelle editieren. Der Status, nach dem du sortieren wolltest, ist genau das, was nicht stillhält.

Option 1: löschen und neu anlegen (atomar)

Wenn der Wert im Base-Table-Key leben muss, bedeutet ihn zu ändern, das alte Item zu entfernen und das neue zu schreiben:

1. DeleteItem  PK=TEAM#7  SK=STATUS#open#TICKET#8842
2. PutItem     PK=TEAM#7  SK=STATUS#pending#TICKET#8842  (same attributes)

Mach es innerhalb eines TransactWriteItems, sodass der Delete und der Put entweder beide gelingen oder beide scheitern — sonst verliert ein Crash zwischen ihnen das Ticket oder dupliziert es. Das funktioniert, aber jede Statusänderung sind nun zwei Writes plus eine Transaktion; in Ordnung für gelegentliche Änderungen, teuer für häufige.

Option 2: den mutablen Wert außerhalb des Base-Key halten (bevorzugt)

Das saubere Design: mach den Base-Table-Key zu etwas Unveränderlichem (die Ticket-ID) und lege den volatilen, sortierbaren Wert auf einen GSI-Sort-Key.

Base:  PK: TICKET#8842   status: "open"   teamId: TEAM#7
GSI:   GSI1PK: TEAM#7    GSI1SK: STATUS#open#TICKET#8842

Jetzt ist eine Statusänderung ein simples UpdateItem auf das status-Attribut des Base-Items — was DynamoDB erlaubt, weil status kein Base-Table-Key ist. DynamoDB re-propagiert dann den GSI-Eintrag automatisch an seine neue sortierte Position. Ein Write, keine Transaktion, kein Delete-Tanz.

JaNein, es ist ein GSI-Sort-KeyStatus wechselt open zu pendingIst der Wert in einemBase-Table-Key?Loeschen + neu anlegen in einerTransaktionSimples UpdateItem; GSIre-propagiert

Der Trade-off: der GSI ist letztendlich konsistent und kostet extra Storage/Writes — aber für einen Wert, der sich oft ändert, ist das weit billiger als Delete-and-Recreate bei jeder Änderung.

Die Keys in DynoTable entwerfen

Baue und previewe die Key Conditions sowohl für den Base-Read als auch für den GSI-Read im DynamoDB Expression Builder.

In DynoTable wählst du dann, durch welchen Index eine Query läuft, und siehst, wie der volatile Wert auf dem GSI sortiert, während das Base-Item seinen unveränderlichen Key behält — beide Reads nebeneinander auf echten Daten.

Eine status-sortierte GSI abfragen, während das Base-Item in DynoTable einen unveränderlichen Key behält.
Eine status-sortierte GSI abfragen, während das Base-Item in DynoTable einen unveränderlichen Key behält.

Fallstricke und nächste Schritte

  • Versuch nie, ein Key-Attribut per UpdateItem zu ändern — es wird abgelehnt; Key-Werte sind für die Lebensdauer des Items fix.
  • Wenn du es verschieben musst, mach Delete+Put in einer Transaktion — nie als zwei ungeschützte Writes.
  • Bevorzuge unveränderliche Base-Keys + einen GSI für jedes Attribut, nach dem du sortierst und das du mutierst.
  • Vergiss die letztendliche Konsistenz des GSI nicht — der neu sortierte Eintrag erscheint nach einer kurzen Propagierungsverzögerung.
  • Verwandt: Sort-Key-Strategien, GSI vs. LSI, Transaktionen.

Willst du sehen, wie ein mutables Attribut auf einem GSI gegenüber der Base-Table sortiert? Lade DynoTable herunter und erkunde deine Indizes direkt.

Aktualisiert