Relationships

You reach for a JOIN because the UI shows users beside their orders, and DynamoDB has no server-side join operator. The expensive mistake is fetching each side with separate GetItem calls — N+1 reads that scale with every row on screen.

Relationships in DynamoDB live in key design. You place related items in the same item collection so one Query returns the graph you need, or you maintain adjacency rows that point across collections. Many-to-many needs an explicit bridge pattern; high fan-out needs composite sort keys and sometimes reference counts to keep collections bounded.

What you can do after

  • Model one-to-many by co-locating children under a parent partition key.
  • Implement many-to-many with adjacency or bridge items without duplicating full records on every edge.
  • Split wide hierarchies with composite sort keys so begins_with queries stay precise.
  • Maintain reference counts atomically when delete rules depend on "no children left."

Reading order

  1. One-to-many — children under one partition key; the base pattern every other relationship extends.
  2. Many-to-many — bridge items and dual-write patterns when either side can list the other.
  3. Adjacency list — graph-shaped data as items and edges; tree walks without recursive SQL.
  4. Composite sort keys — encode hierarchy in the sort key so range queries stay selective.
  5. Reference counts — conditional updates that gate deletes when fan-out must stay consistent.
0 of 6 readQuiz

A user profile at PK = USER#88 with orders at SK = ORDER#2026-08-01#K4 lets you paint a profile screen from one Query. A many-to-many tag graph needs bridge rows — skipping that step leaves you Scanning for edges.

Adjacency lists model trees and shallow graphs with PARENT# / CHILD# sort-key prefixes so one begins_with query returns direct children. Composite sort keys encode paths like LOCATION#US#CA#SF so range queries stay within a subtree. Reference counts on a parent item gate deletes: referenceCount = :zero in a condition expression prevents removing a category that still has products attached. Each pattern trades write complexity for read efficiency — pick the one that matches how often you list vs how often you reshape the graph.

Hands-on in DynoTable

Download DynoTable and open a table with parent/child keys. Run a Query on the parent partition and watch the grid return the whole collection in sort order. Right-click a composite key cell and filter to a prefix to see how entity facets group in practice.

When you want the relational view anyway, the SQL Workbench runs JOIN client-side over the rows you already fetched. That join is bounded by what DynamoDB returned — it does not add a server-side join operator. Use it to validate a key design, not to paper over a missing access pattern.

For ad-hoc parent/child layouts, the single-table design planner proposes PK/SK placement from your stated reads.