At a glance
Key concepts and capabilities
GetItem by exact key, Query on a partition key plus a sort-key condition; Scan is the wrong answerPK=USER#123, SK=ORDER#… packs related entities so one Query returns them togetherattribute_not_exists for insert-if-absent, version = :expected for optimistic concurrencyTransactWriteItems is all-or-nothing across up to 100 items, at twice the costUse cases
One table, one round trip
There are no joins, so related entities are packed under one partition key and
retrieved together: PK=USER#123 with a sort key range between ORDER# and
ORDER#~ returns the profile and the recent orders in a single Query. It reads
strangely and it is the idiomatic pattern.
Exactly-once without a lock
A conditional write is the concurrency primitive: PutItem with
attribute_not_exists(pk) succeeds for the first caller and fails for every
retry, which is an idempotency key, a username claim or a lock, depending on what
you put in the key.
Fanning changes out with Streams
Every change can be published in order per partition key and kept for 24 hours. That stream is how a search index, an aggregate or a notification is driven from the table without the application writing to two places and getting them out of step.
Spreading a hot partition
Traffic concentrated on one partition key is throttled even though the table has capacity, because a partition has its own ceiling. The fix is in the key: add a suffix and fan the reads across it, or bucket by time so today's writes are not all one key.