Amazon DynamoDB

System Architecture

intermediate
nosqlawsmanaged-servicescalabilityperformancekey-value-store

Fully managed NoSQL database service designed for high performance at any scale

Amazon DynamoDB

Amazon DynamoDB is a fully managed NoSQL database service that provides fast and predictable performance with seamless scalability. It's designed to handle any amount of traffic and data while maintaining single-digit millisecond latency.

Overview

DynamoDB is a key-value and document database that delivers single-digit millisecond performance at any scale. It's a fully managed, multiregion, multimaster database with built-in security, backup and restore, and in-memory caching for internet-scale applications.

Key Features

  • Fully Managed: No servers to provision, patch, or manage
  • Single-Digit Millisecond Latency: Consistent performance at any scale
  • Built-in Security: Encryption at rest and in transit
  • Global Tables: Multi-region, multi-active replication
  • On-Demand Scaling: Automatically scales up and down
  • Point-in-Time Recovery: Continuous backups with 35-day retention

Architecture

Core Components

System Architecture Diagram

Data Model

Tables

  • Primary container for data
  • Must have a primary key
  • No size limit (unlimited items)

Items

  • Collection of attributes
  • Maximum item size: 400 KB
  • Attributes are key-value pairs

Attributes

  • Name-value pairs
  • Dynamically typed
  • Can be scalar, set, or document

Primary Key

  • Partition Key: Single attribute that uniquely identifies an item
  • Composite Key: Partition key + sort key combination

Data Operations

Write Operations

PutItem

// Put a new item or replace existing item
const params = {
    TableName: 'Users',
    Item: {
        'UserId': { S: 'user123' },
        'Name': { S: 'John Doe' },
        'Email': { S: 'john@example.com' },
        'Age': { N: '30' }
    }
};

await dynamodb.putItem(params).promise();

UpdateItem

// Update specific attributes
const params = {
    TableName: 'Users',
    Key: {
        'UserId': { S: 'user123' }
    },
    UpdateExpression: 'SET #name = :name, #age = :age',
    ExpressionAttributeNames: {
        '#name': 'Name',
        '#age': 'Age'
    },
    ExpressionAttributeValues: {
        ':name': { S: 'Jane Doe' },
        ':age': { N: '31' }
    },
    ReturnValues: 'ALL_NEW'
};

const result = await dynamodb.updateItem(params).promise();

Read Operations

GetItem

// Retrieve a single item
const params = {
    TableName: 'Users',
    Key: {
        'UserId': { S: 'user123' }
    },
    ProjectionExpression: 'UserId, Name, Email'
};

const result = await dynamodb.getItem(params).promise();

Query

// Query items with same partition key
const params = {
    TableName: 'Orders',
    KeyConditionExpression: 'CustomerId = :customerId',
    ExpressionAttributeValues: {
        ':customerId': { S: 'customer123' }
    }
};

const result = await dynamodb.query(params).promise();

Performance Optimization

Capacity Modes

Provisioned Mode

// Set up provisioned capacity
const params = {
    TableName: 'Users',
    ProvisionedThroughput: {
        ReadCapacityUnits: 100,
        WriteCapacityUnits: 50
    }
};

await dynamodb.updateTable(params).promise();

On-Demand Mode

// Enable on-demand billing
const params = {
    TableName: 'Users',
    BillingMode: 'PAY_PER_REQUEST'
};

await dynamodb.updateTable(params).promise();

Best Practices

Single Table Design

// Design for single table with different entity types
const user = {
    PK: 'USER#user123',
    SK: 'PROFILE',
    EntityType: 'User',
    Name: 'John Doe',
    Email: 'john@example.com'
};

const order = {
    PK: 'USER#user123',
    SK: 'ORDER#order456',
    EntityType: 'Order',
    OrderDate: '2024-01-15',
    Total: 99.99
};

Access Patterns

// Query user profile
const userParams = {
    TableName: 'AppTable',
    KeyConditionExpression: 'PK = :pk AND SK = :sk',
    ExpressionAttributeValues: {
        ':pk': 'USER#user123',
        ':sk': 'PROFILE'
    }
};

// Query user orders
const ordersParams = {
    TableName: 'AppTable',
    KeyConditionExpression: 'PK = :pk AND begins_with(SK, :sk)',
    ExpressionAttributeValues: {
        ':pk': 'USER#user123',
        ':sk': 'ORDER#'
    }
};

Interview Questions

Basic Level

Q1: What is DynamoDB and what are its key features?

Answer: DynamoDB is a fully managed NoSQL database service that provides:

  • Single-digit millisecond latency
  • Automatic scaling
  • Built-in security and encryption
  • Global tables for multi-region replication
  • Point-in-time recovery

Q2: What are the different capacity modes in DynamoDB?

Answer:

  • Provisioned Mode: Pre-allocate read/write capacity units
  • On-Demand Mode: Pay per request, automatic scaling
  • DynamoDB Accelerator (DAX): In-memory cache for microsecond latency

Intermediate Level

Q3: How do you design a DynamoDB table for optimal performance?

Answer:

// Design principles:
// 1. Single table design
// 2. Access pattern driven
// 3. Use composite keys effectively
// 4. Minimize hot partitions

const tableDesign = {
    TableName: 'ECommerceApp',
    KeySchema: [
        { AttributeName: 'PK', KeyType: 'HASH' },
        { AttributeName: 'SK', KeyType: 'RANGE' }
    ]
};

Q4: What are the differences between Query and Scan operations?

Answer:

  • Query: Uses primary key, efficient, can use sort key conditions
  • Scan: Examines every item, less efficient, uses filter expressions
  • Best Practice: Use Query whenever possible, Scan only when necessary

Advanced Level

Q5: How would you implement transactions in DynamoDB?

Answer:

// DynamoDB Transactions
const transactionParams = {
    TransactItems: [
        {
            Put: {
                TableName: 'Users',
                Item: {
                    'UserId': { S: 'user123' },
                    'Name': { S: 'John Doe' },
                    'Balance': { N: '100' }
                }
            }
        },
        {
            Put: {
                TableName: 'Orders',
                Item: {
                    'OrderId': { S: 'order456' },
                    'UserId': { S: 'user123' },
                    'Amount': { N: '50' }
                }
            }
        }
    ]
};

try {
    await dynamodb.transactWrite(transactionParams).promise();
} catch (error) {
    if (error.code === 'TransactionCanceledException') {
        console.log('Transaction failed:', error.message);
    }
}

Real-World Scenarios

Scenario 1: E-commerce Product Catalog

Problem: Store millions of products with complex search requirements.

Solution: Single table design with GSI for different access patterns.

// Product item
const product = {
    PK: 'PRODUCT#product123',
    SK: 'DETAILS',
    EntityType: 'Product',
    Name: 'Laptop',
    Category: 'Electronics',
    Price: 999.99,
    Brand: 'TechCorp',
    InStock: true
};

Scenario 2: Real-time Gaming Leaderboard

Problem: Track player scores and maintain real-time leaderboards.

Solution: Use sort keys for ranking and TTL for data expiration.

// Player score
const score = {
    PK: 'LEADERBOARD#daily',
    SK: `SCORE#${1000000 - playerScore}#${playerId}`,
    EntityType: 'Score',
    PlayerId: playerId,
    Score: playerScore,
    Timestamp: Date.now(),
    TTL: Math.floor(Date.now() / 1000) + (24 * 60 * 60) // 24 hours
};

Conclusion

DynamoDB is a powerful NoSQL database that excels at high-performance, scalable applications. Key success factors include:

  1. Proper Data Modeling: Design for access patterns, not data relationships
  2. Capacity Planning: Choose appropriate capacity mode and monitor usage
  3. Performance Optimization: Use Query over Scan, implement caching
  4. Security: Leverage built-in encryption and IAM policies
  5. Monitoring: Set up CloudWatch alarms and track key metrics

When implemented correctly, DynamoDB can handle massive scale while maintaining consistent performance and reducing operational overhead.