Single-Table Design

In traditional SQL (and even some NoSQL databases like MongoDB), the standard practice is to create a separate table for each entity type: Users, Orders, Products. In DynamoDB, the industry-standard pattern is Single-Table Design.

[!IMPORTANT] The Paradigm Shift: In SQL, you model your data structure (schema) first. In DynamoDB, you must design for your access patterns first. If you don’t know exactly how you will query the data, you cannot design a functional DynamoDB table.

1. Why One Table?

DynamoDB charges you based on Read Capacity Units (RCU) and Write Capacity Units (WCU). It also prioritizes consistent, single-digit millisecond latency at any scale.

The Relational Approach (SQL)

To fetch a User and their last 5 Orders, a relational database must:

  1. Find the User row in the Users table (Random I/O).
  2. Find the Order rows in the Orders table (Random I/O).
  3. Join them in memory (CPU intensive).

As your data grows, these joins become slower and more expensive.

The DynamoDB Approach (Single-Table)

You store the User item and the Order items in the same table, sharing the same Partition Key (e.g., USER#123).

  1. DynamoDB goes to the partition for USER#123.
  2. It reads a contiguous block of data (User + Orders).
  3. It returns the result in a single request.

This is called an Item Collection. It allows you to fetch a hierarchy of data with O(1) complexity, regardless of whether you have 10 users or 10 billion.


2. Interactive: The Cost of Joins

Compare the “Join” operation in SQL versus the “Pre-Joined” retrieval in DynamoDB.

SQL: The "CPU Tax"

User
Ord
Ord
Ready

DynamoDB: The "Storage Tax"

Pre-Joined on Disk

3. Key Differences: SQL vs NoSQL

Feature SQL (Relational) DynamoDB (Single-Table)
Joins Performed at Query Time (Flexible). Performed at Write Time (Pre-joined).
Schema Rigid and normalized (3NF). Flexible and denormalized.
Scaling Vertical (Larger Servers). Horizontal (More Partitions).
Querying Flexible filters (WHERE x AND y). Rigid Access Patterns (PK = X).

4. The “Access Pattern First” Rule

Because DynamoDB is optimized for scale, it removes the ability to do expensive operations like arbitrary joins or full table scans. This means you cannot simply “dump” data into a table and figure out how to query it later.

[!TIP] The Golden Rule: You must identify every single way your application needs to read data before you create your table.

Example Access Patterns:

  1. getUserProfile(userId)
  2. getRecentOrders(userId)
  3. getOrderDetails(orderId)

Each of these patterns dictates how you will structure your Primary Key, which we will cover in the next chapter.

Next Steps

Now that you understand why we put everything in one table, let’s learn how DynamoDB physically stores this data using Partition Keys and Sort Keys.