accesspatterns.dev
← All models

logistics

Fleet Registry

Two attributes that must both be unique, enforced with lock items.

A vehicle has a registration plate and a chassis number, and neither may repeat across the fleet. DynamoDB enforces uniqueness on the primary key and nowhere else, so each of those values becomes an item of its own whose only job is to be impossible to create twice.

The model

Vehicle

The vehicle record itself.

pk
VEHICLE#<vehicleId>

Attributes: plate (S), chassis (S), depot (S), addedAt (N)

PlateLock

An item whose entire value is that it exists.

pk
PLATE#<plate>

Attributes: vehicleId (S)

ChassisLock

The same, for the chassis number.

pk
CHASSIS#<chassis>

Attributes: vehicleId (S)

Access patterns

  • PutItemRegister the vehicle

    Write the vehicle row itself.

  • PutItemClaim the plate

    Write the plate lock, only if nobody holds it.

  • PutItemClaim the chassis number

    The same, for the chassis lock.

  • GetItemRead a vehicle

    The vehicle record by id.

Design notes

Uniqueness only exists on the keywhy

There is no unique constraint to declare on an attribute. The only thing DynamoDB will not duplicate is a primary key, so anything that must be unique has to become one - which is why this table holds three kinds of item and only two of them are vehicles.

A lock item is a row that means takenwhy

PLATE#ka19 xtr carries almost nothing beyond a pointer back to the vehicle holding it. Its value is entirely in existing, because a conditional put on attribute_not_exists(PK) is refused when it does. Note the values are normalised - lowercased, spacing fixed - since a plate written two ways would produce two locks and no uniqueness at all.

Three writes that must not half-succeedwhy

The two claims and the vehicle row are three separate writes, and any of them can fail its condition. Run one at a time, a failure at the second leaves a plate locked to a vehicle that will never exist, and nothing in the model releases it. TransactWriteItems binds all three so they land together or not at all - which is why this pattern is usually taught with transactions rather than as three puts.

Releasing is a policy the model does not choosetrade-off

A lock is gone when its row is deleted, and the next claimant then succeeds. Whether a retired plate should ever be reclaimable, and whether the delete belongs in the same transaction as retiring the vehicle, are decisions the key design does not make for you. It only guarantees that while the row exists, nobody else can have it.

Claiming is a design here, not a live demonstrationtrade-off

The engine does perform conditional puts - a claim succeeds once and the retry is refused - but it does not support TransactWriteItems at all, and the resolver does not emit writes as runnable regardless. The console reads the table; the claiming, and the transaction that ought to bind it, are described rather than shown.

Taught in the course

  • Claim it, or fail - A ConditionExpression lets a write happen only if the data still allows it.
fleet-registry
Try an example

The vehicle record by id.

PK(pk)
addedAt
chassis
depot
plate
vehicleId
VEHICLE#v-3301
1733097600N
wvz5r7100pk204118S
leedsS
ka19 xtrS
VEHICLE#v-3417
1765929600N
wvz5r7100rk318902S
bristolS
lb21 hneS
PLATE#ka19 xtr
v-3301S
PLATE#lb21 hne
v-3417S
CHASSIS#wvz5r7100pk204118
v-3301S
CHASSIS#wvz5r7100rk318902
v-3417S

Run an operation to see the raw engine response.

table fleet-registrykeys PKitems 6

The in-browser engine is a preview build. Transactions, vector search, streams, tags and TTL are among the operations it doesn't implement yet.