⚡ Deep Dive into DynamoDB: Design, Modeling, and Best Practices
⚡ Quick Dive
Overview & Key Takeaways
Amazon DynamoDB is a fully managed NoSQL key-value and document database that delivers single-digit millisecond performance at any scale. It is serverless, supports automatic scaling, built-in security, and multi-region replication.
🧠 Core Concepts
🔹 Tables, Items, and Attributes
- Table: Collection of data
- Item: Single row of data (like a document)
- Attribute: Field within an item (like a column)
// Sample item in DynamoDB (JSON format)
{
"UserId": "user
---
## 📖 Extended Guide
**Amazon DynamoDB** is a fully managed NoSQL key-value and document database that delivers single-digit millisecond performance at any scale. It is serverless, supports automatic scaling, built-in security, and multi-region replication.
---
## 🧠 Core Concepts
### 🔹 Tables, Items, and Attributes
- **Table**: Collection of data
- **Item**: Single row of data (like a document)
- **Attribute**: Field within an item (like a column)
// Sample item in DynamoDB (JSON format) { "UserId": "user-123", "Name": "Alice", "Age": 30, "Email": "alice@example.com" }
---
### 🔹 Primary Key
Every item must have a **primary key**, which can be:
- **Partition key only** (simple key)
- **Partition key + Sort key** (composite key)
The partition key determines the **data distribution** across storage partitions.
// Example composite key Partition Key: "UserId" = "user-123" Sort Key: "OrderDate" = "2024-10-10"
---
### 🔹 Secondary Indexes
- **Global Secondary Index (GSI)**: Query using non-primary key attributes
- **Local Secondary Index (LSI)**: Adds sort key to the existing partition key
Indexes must be **defined at table creation (LSI)** or can be **added later (GSI)**.
---
### 🔹 Read and Write Capacity Modes
1. **On-Demand**: Auto-scales based on usage (pay per request)
2. **Provisioned**: Manually set read/write units (cheaper with predictable load)
// Provisioned example Read Capacity Units (RCU) = 5 Write Capacity Units (WCU) = 10
Use **DAX (DynamoDB Accelerator)** to cache reads and improve performance.
---
## 📊 Data Modeling in DynamoDB
DynamoDB is **not relational** — it's designed for **access patterns**.
### ✅ Design Principles
- **One table per application** (single-table design)
- Predefine your query patterns
- Use compound keys and GSIs to shape access
- Store denormalized or nested data when appropriate
// Example item with embedded data { "UserId": "user-123", "Type": "Profile", "Profile": { "Name": "Alice", "Email": "alice@example.com" } }
> ⚠️ Avoid joins. You query based on access patterns, not relations.
---
## 🧪 Querying & Scanning
### 📌 Query
Efficient — uses partition key and optional sort key conditions.
aws dynamodb query
--table-name Users
--key-condition-expression "UserId = :uid"
--expression-attribute-values '{":uid":{"S":"user-123"}}'
### 📌 Scan
Inefficient — reads all items. Use only for small datasets or batch jobs.
---
## 🔐 Security & Access Control
- **IAM policies**: Grant fine-grained access control
- **Encryption at rest**: AWS KMS integrated
- **Encryption in transit**: Enabled by default
- **VPC endpoints**: Secure internal traffic
// IAM example: Allow read-only access { "Effect": "Allow", "Action": [ "dynamodb:GetItem", "dynamodb:Query", "dynamodb:Scan" ], "Resource": "arn:aws:dynamodb:region:acct-id:table/Users" }
---
## ♻️ Streams and Triggers
Enable **DynamoDB Streams** to capture item changes (insert, update, delete).
- Stream events can trigger **AWS Lambda**
- Used for audit logging, replication, and downstream processing
// Event structure (example) { "eventName": "INSERT", "dynamodb": { "Keys": { "UserId": { "S": "user-123" } }, "NewImage": { "Name": { "S": "Alice" } } } }
---
## 🚦 Best Practices
| Practice | Reason |
|----------------------------------|------------------------------------------------|
| Design access patterns first | Helps with schema design in NoSQL |
| Prefer `Query` over `Scan` | Better performance and cost |
| Avoid hot partitions | Use high-cardinality partition keys |
| Use DAX for heavy-read workloads | In-memory caching layer |
| Use TTL | Automatically delete expired data |
| Monitor with CloudWatch | Track latency, throttles, WCU/RCU usage |
---
## 🔥 When to Use DynamoDB
- Applications with **predictable access patterns**
- **Serverless apps** using AWS Lambda
- Workloads needing **massive scale with low latency**
- Use cases: IoT, gaming, real-time analytics, chat apps
---
## 🛑 When Not to Use
- Complex relational joins or multi-table transactions
- Heavy ad-hoc queries
- High write throughput without thoughtful partitioning
---
## 📚 Resources
- [DynamoDB Docs](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html)
- [DynamoDB Data Modeling](https://www.alexdebrie.com/)
- [AWS DynamoDB CLI Reference](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/)
- [NoSQL Design Patterns](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/bp-general-nosql-design.html)
---