Amazon DynamoDB
DynamoDB is a fully managed NoSQL database built around key-value and document data models, with low-latency access at scale. Effective DynamoDB design starts by modeling tables around application access patterns rather than around normalized relational entities.
A DynamoDB table stores items identified by a primary key. The primary key can be a simple partition key or a composite key consisting of a partition key and sort key. Items can contain flexible attributes, so different items in the same table do not need identical fields.
With a composite primary key, DynamoDB groups items by partition key and orders them by sort key. This makes queries such as "all orders for customer X within a time range" efficient because the partition key identifies the logical collection and the sort key supports conditions within it.
DynamoDB is designed around known access patterns. Instead of starting with normalized tables and adding indexes afterward, you generally identify the reads and writes the application needs, then choose keys and indexes that support those operations efficiently. A `Query` targets a specific partition-key value, while a `Scan` examines items across a table or index and is usually unsuitable for frequent application reads.
Secondary indexes provide alternative key structures. A global secondary index (GSI) can use a different partition key and sort key from the base table and can be queried independently. A local secondary index (LSI) shares the base table's partition key while providing a different sort key, and it must be defined when the table is created.
For Java applications, the AWS SDK for Java 2.x provides DynamoDB clients and enhanced APIs that map Java objects to DynamoDB items. Production designs also need to consider capacity, consistency, item size, hot partitions, conditional writes, pagination, retries, and transaction requirements.
Key points
- Model tables around access patterns and query requirements.
- A primary key is either a partition key alone or a partition key plus sort key.
- Use `Query` for targeted reads and avoid relying on `Scan` for normal request paths.
- GSIs provide alternate access paths; LSIs retain the base table's partition key.
- Design for partition distribution, capacity, consistency, pagination, and conditional writes.
Interview questions
How would you choose a primary key for a DynamoDB table?
Start by listing the application's required access patterns rather than beginning with entities. Choose a partition key that lets the important requests locate data directly while distributing traffic across partitions. If related items must be retrieved or ordered within the same partition, add a sort key. The design should also avoid concentrating excessive traffic or storage under one partition-key value.
What is the difference between Query and Scan in DynamoDB?
A `Query` retrieves items for a particular partition-key value and can restrict the sort key when one exists. A `Scan` reads through items in the table or index without requiring a specific partition-key value. Because a scan can touch a large amount of data, it is generally a poor choice for latency-sensitive request paths. Query is normally the operation you want when the access pattern can be expressed through the key schema.
What is a hot partition, and how can you avoid it?
A hot partition occurs when traffic or stored data becomes disproportionately concentrated on one partition-key value. This can create a bottleneck even when the table as a whole has substantial capacity. Choosing high-cardinality, well-distributed partition-key values helps spread requests. In suitable workloads, write-sharding or another key-design strategy can distribute otherwise concentrated traffic.
When would you use a global secondary index?
Use a GSI when an important access pattern cannot be efficiently served by the table's primary key. A GSI provides another key structure that can be queried independently of the base table's primary-key arrangement. For example, a table keyed by customer might need an alternate access path by email address or status. The index should be justified by a real query pattern because indexes add storage and write-related overhead.
How would you design a DynamoDB-backed order system for a Java service?
I would first enumerate the required operations, such as retrieving a customer's orders, fetching one order, and listing recent orders. A composite key such as `customerId` plus an order timestamp or order identifier could support customer-centric queries, while a GSI could support another high-value access pattern if necessary. I would decide consistency requirements explicitly and handle pagination, retries, conditional writes, and capacity behavior in the service layer. Finally, I would test the key distribution and workload rather than assuming that a logically correct schema will automatically distribute traffic well.