Skip to content

One table, an application's worth of questions

Generic keys and one overloaded index answer five access patterns with no join and no scan.

Why

This is the whole course in one table. A conference platform has conferences, sessions, speakers and registrations, and five questions to answer. Every item lives in one table, keyed generically, with one overloaded index, GSI1, shared across two entity types.

Run the five examples. A conference and its agenda are one Query; a session and its attendees are another. GSI1 re-keys sessions by speaker and registrations by attendee, so the same index answers both 'every talk this speaker gives' and 'every session this attendee booked'. The fifth is a plain GetItem. Five access patterns, every one a Query or a GetItem, never a join and never a scan.

Model backwards from your access patterns: generic keys and one overloaded index let a single table serve an entire application.

Try it. Then change it.

Predict what each request will do. Run it, inspect the response, then change a value in the workbench and try again.

  1. A conference and its sessions share a partition, so one Query returns the lot, sessions in start-time order.

  2. Registrations live under their session's partition, so a session's attendees are one Query.

  3. GSI1 re-keys sessions by speaker, so every talk Okafor gives, across conferences, is one Query.

  4. The same GSI1, a different entity: registrations re-keyed by attendee. One index, two questions.

  5. The point read that needs no index: one attendee's registration for a session.

Built on this

ConferenceDynamoDB workbench
Ready to run
Explore an access patternSelect to load & run

A conference and its sessions share a partition, so one Query returns the lot, sessions in start-time order.

Request
Execute against the local Dynoxide engine
ReturnedFiltered outChanged
pk(pk)
sk(sk)
name
city
gsi1pk
gsi1sk
title
room
meal
CONF#north26
CONF#north26S
NorthConf 2026S
LeedsS
—
—
—
—
—
CONF#north26
SESS#2026-09-10T09:00#s1S
—
—
SPEAKER#okaforS
SESS#2026-09-10T09:00S
WASM at the edgeS
AS
—
CONF#north26
SESS#2026-09-10T11:00#s2S
—
—
SPEAKER#meiS
SESS#2026-09-10T11:00S
Vector searchS
BS
—
CONF#north26
SESS#2026-09-10T14:00#s3S
—
—
SPEAKER#okaforS
SESS#2026-09-10T14:00S
Edge cachingS
AS
—
CONF#south26
CONF#south26S
SouthConf 2026S
BristolS
—
—
—
—
—
CONF#south26
SESS#2026-11-02T10:00#s4S
—
—
SPEAKER#rajS
SESS#2026-11-02T10:00S
Rust for dataS
MainS
—
SESS#s1
REG#danaS
—
—
ATTENDEE#danaS
REG#north26#s1S
—
—
vegS
SESS#s1
REG#lenaS
—
—
ATTENDEE#lenaS
REG#north26#s1S
—
—
noneS
SESS#s2
REG#danaS
—
—
ATTENDEE#danaS
REG#north26#s2S
—
—
vegS
SESS#s4
REG#omarS
—
—
ATTENDEE#omarS
REG#south26#s4S
—
—
halalS
Awaiting request
Your next query starts here.

Choose an access pattern above, or build your own request. See what comes back and what it costs.

Powered by DynoxideWASMStarts on your first run · Runs locally in your browser