{"id":"dynamodb","name":"dynamodb","summary":"AWS DynamoDB NoSQLデータベースでスケーラブルなデータ保存が可能です。テーブルスキーマの設計、クエリの作成、インデックスの設定、容量管理、単一テーブル設計の実装、パフォーマンス問題のトラブルシューティングなどに活用してください。","body":"# AWS DynamoDB\n\nAmazon DynamoDB is a fully managed NoSQL database service providing fast, predictable performance at any scale. It supports key-value and document data structures.\n\n## Table of Contents\n\n- [Core Concepts](#core-concepts)\n- [Common Patterns](#common-patterns)\n- [CLI Reference](#cli-reference)\n- [Best Practices](#best-practices)\n- [Troubleshooting](#troubleshooting)\n- [References](#references)\n\n## Core Concepts\n\n### Keys\n\n| Key Type | Description |\n|----------|-------------|\n| **Partition Key (PK)** | Required. Determines data distribution |\n| **Sort Key (SK)** | Optional. Enables range queries within partition |\n| **Composite Key** | PK + SK combination |\n\n### Secondary Indexes\n\n| Index Type | Description |\n|------------|-------------|\n| **GSI (Global Secondary Index)** | Different PK/SK, separate throughput, eventually consistent |\n| **LSI (Local Secondary Index)** | Same PK, different SK, shares table throughput, strongly consistent option |\n\n### Capacity Modes\n\n| Mode | Use Case |\n|------|----------|\n| **On-Demand** | Unpredictable traffic, pay-per-request |\n| **Provisioned** | Predictable traffic, lower cost, can use auto-scaling |\n\n## Common Patterns\n\n### Create a Table\n\n**AWS CLI:**\n\n```bash\naws dynamodb create-table \\\n  --table-name Users \\\n  --attribute-definitions \\\n    AttributeName=PK,AttributeType=S \\\n    AttributeName=SK,AttributeType=S \\\n  --key-schema \\\n    AttributeName=PK,KeyType=HASH \\\n    AttributeName=SK,KeyType=RANGE \\\n  --billing-mode PAY_PER_REQUEST\n```\n\n**boto3:**\n\n```python\nimport boto3\n\ndynamodb = boto3.resource('dynamodb')\n\ntable = dynamodb.create_table(\n    TableName='Users',\n    KeySchema=[\n        {'AttributeName': 'PK', 'KeyType': 'HASH'},\n        {'AttributeName': 'SK', 'KeyType': 'RANGE'}\n    ],\n    AttributeDefinitions=[\n        {'AttributeName': 'PK', 'AttributeType': 'S'},\n        {'AttributeName': 'SK', 'AttributeType': 'S'}\n    ],\n    BillingMode='PAY_PER_REQUEST'\n)\n\ntable.wait_until_exists()\n```\n\n### Basic CRUD Operations\n\n```python\nimport boto3\nfrom boto3.dynamodb.conditions import Key, Attr\n\ndynamodb = boto3.resource('dynamodb')\ntable = dynamodb.Table('Users')\n\n# Put item\ntable.put_item(\n    Item={\n        'PK': 'USER#123',\n        'SK': 'PROFILE',\n        'name': 'John Doe',\n        'email': 'john@example.com',\n        'created_at': '2024-01-15T10:30:00Z'\n    }\n)\n\n# Get item\nresponse = table.get_item(\n    Key={'PK': 'USER#123', 'SK': 'PROFILE'}\n)\nitem = response.get('Item')\n\n# Update item\ntable.update_item(\n    Key={'PK': 'USER#123', 'SK': 'PROFILE'},\n    UpdateExpression='SET #name = :name, updated_at = :updated',\n    ExpressionAttributeNames={'#name': 'name'},\n    ExpressionAttributeValues={\n        ':name': 'John Smith',\n        ':updated': '2024-01-16T10:30:00Z'\n    }\n)\n\n# Delete item\ntable.delete_item(\n    Key={'PK': 'USER#123', 'SK': 'PROFILE'}\n)\n```\n\n### Query Operations\n\n```python\n# Query by partition key\nresponse = table.query(\n    KeyConditionExpression=Key('PK').eq('USER#123')\n)\n\n# Query with sort key condition\nresponse = table.query(\n    KeyConditionExpression=Key('PK').eq('USER#123') & Key('SK').begins_with('ORDER#')\n)\n\n# Query with filter\nresponse = table.query(\n    KeyConditionExpression=Key('PK').eq('USER#123'),\n    FilterExpression=Attr('status').eq('active')\n)\n\n# Query with projection\nresponse = table.query(\n    KeyConditionExpression=Key('PK').eq('USER#123'),\n    ProjectionExpression='PK, SK, #name, email',\n    ExpressionAttributeNames={'#name': 'name'}\n)\n\n# Paginated query\npaginator = dynamodb.meta.client.get_paginator('query')\nfor page in paginator.paginate(\n    TableName='Users',\n    KeyConditionExpression='PK = :pk',\n    ExpressionAttributeValues={':pk': {'S': 'USER#123'}}\n):\n    for item in page['Items']:\n        print(item)\n```\n\n### Batch Operations\n\n```python\n# Batch write (up to 25 items)\nwith table.batch_writer() as batch:\n    for i in range(100):\n        batch.put_item(Item={\n            'PK': f'USER#{i}',\n            'SK': 'PROFILE',\n            'name': f'User {i}'\n        })\n\n# Batch get (up to 100 items)\ndynamodb = boto3.resource('dynamodb')\nresponse = dynamodb.batch_get_item(\n    RequestItems={\n        'Users': {\n            'Keys': [\n                {'PK': 'USER#1', 'SK': 'PROFILE'},\n                {'PK': 'USER#2', 'SK': 'PROFILE'}\n            ]\n        }\n    }\n)\n```\n\n### Create GSI\n\n```bash\naws dynamodb update-table \\\n  --table-name Users \\\n  --attribute-definitions AttributeName=email,AttributeType=S \\\n  --global-secondary-index-updates '[\n    {\n      \"Create\": {\n        \"IndexName\": \"email-index\",\n        \"KeySchema\": [{\"AttributeName\": \"email\", \"KeyType\": \"HASH\"}],\n        \"Projection\": {\"ProjectionType\": \"ALL\"}\n      }\n    }\n  ]'\n```\n\n### Conditional Writes\n\n```python\nfrom botocore.exceptions import ClientError\n\n# Only put if item doesn't exist\ntry:\n    table.put_item(\n        Item={'PK': 'USER#123', 'SK': 'PROFILE', 'name': 'John'},\n        ConditionExpression='attribute_not_exists(PK)'\n    )\nexcept ClientError as e:\n    if e.response['Error']['Code'] == 'ConditionalCheckFailedException':\n        print(\"Item already exists\")\n\n# Optimistic locking with version\ntable.update_item(\n    Key={'PK': 'USER#123', 'SK': 'PROFILE'},\n    UpdateExpression='SET #name = :name, version = version + :inc',\n    ConditionExpression='version = :current_version',\n    ExpressionAttributeNames={'#name': 'name'},\n    ExpressionAttributeValues={\n        ':name': 'New Name',\n        ':inc': 1,\n        ':current_version': 5\n    }\n)\n```\n\n## CLI Reference\n\n### Table Operations\n\n| Command | Description |\n|---------|-------------|\n| `aws dynamodb create-table` | Create table |\n| `aws dynamodb describe-table` | Get table info |\n| `aws dynamodb update-table` | Modify table/indexes |\n| `aws dynamodb delete-table` | Delete table |\n| `aws dynamodb list-tables` | List all tables |\n\n### Item Operations\n\n| Command | Description |\n|---------|-------------|\n| `aws dynamodb put-item` | Create/replace item |\n| `aws dynamodb get-item` | Read single item |\n| `aws dynamodb update-item` | Update item attributes |\n| `aws dynamodb delete-item` | Delete item |\n| `aws dynamodb query` | Query by key |\n| `aws dynamodb scan` | Full table scan |\n\n### Batch Operations\n\n| Command | Description |\n|---------|-------------|\n| `aws dynamodb batch-write-item` | Batch write (25 max) |\n| `aws dynamodb batch-get-item` | Batch read (100 max) |\n| `aws dynamodb transact-write-items` | Transaction write |\n| `aws dynamodb transact-get-items` | Transaction read |\n\n## Best Practices\n\n### Data Modeling\n\n- **Design for access patterns** — know your queries before designing\n- **Use composite keys** — PK for grouping, SK for sorting/filtering\n- **Prefer query over scan** — scans are expensive\n- **Use sparse indexes** — only items with index attributes are indexed\n- **Consider single-table design** for related entities\n\n### Performance\n\n- **Distribute partition keys evenly** — avoid hot partitions\n- **Use batch operations** to reduce API calls\n- **Enable DAX** for read-heavy workloads\n- **Use projections** to reduce data transfer\n\n### Cost Optimization\n\n- **Use on-demand** for variable workloads\n- **Use provisioned + auto-scaling** for predictable workloads\n- **Set TTL** for expiring data\n- **Archive to S3** for cold data\n\n## Troubleshooting\n\n### Throttling\n\n**Symptom:** `ProvisionedThroughputExceededException`\n\n**Causes:**\n- Hot partition (uneven key distribution)\n- Burst traffic exceeding capacity\n- GSI throttling affecting base table\n\n**Solutions:**\n\n```python\n# Use exponential backoff\nimport time\nfrom botocore.config import Config\n\nconfig = Config(\n    retries={\n        'max_attempts': 10,\n        'mode': 'adaptive'\n    }\n)\ndynamodb = boto3.resource('dynamodb', config=config)\n```\n\n### Hot Partitions\n\n**Debug:**\n\n```bash\n# Check consumed capacity by partition\naws cloudwatch get-metric-statistics \\\n  --namespace AWS/DynamoDB \\\n  --metric-name ConsumedReadCapacityUnits \\\n  --dimensions Name=TableName,Value=Users \\\n  --start-time $(date -d '1 hour ago' -u +%Y-%m-%dT%H:%M:%SZ) \\\n  --end-time $(date -u +%Y-%m-%dT%H:%M:%SZ) \\\n  --period 60 \\\n  --statistics Sum\n```\n\n**Solutions:**\n- Add randomness to partition keys\n- Use write sharding\n- Distribute access across partitions\n\n### Query Returns No Items\n\n**Debug checklist:**\n1. Verify key values exactly match (case-sensitive)\n2. Check key types (S, N, B)\n3. Confirm table/index name\n4. Review filter expressions (they apply AFTER read)\n\n### Scan Performance\n\n**Issue:** Scans are slow and expensive\n\n**Solutions:**\n- Use parallel scan for large tables\n- Create GSI for the access pattern\n- Use filter expressions to reduce returned data\n\n```python\n# Parallel scan\nimport concurrent.futures\n\ndef scan_segment(segment, total_segments):\n    return table.scan(\n        Segment=segment,\n        TotalSegments=total_segments\n    )\n\nwith concurrent.futures.ThreadPoolExecutor() as executor:\n    results = list(executor.map(\n        lambda s: scan_segment(s, 4),\n        range(4)\n    ))\n```\n\n## References\n\n- [DynamoDB Developer Guide](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/)\n- [DynamoDB API Reference](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/)\n- [DynamoDB CLI Reference](https://docs.aws.amazon.com/cli/latest/reference/dynamodb/)\n- [boto3 DynamoDB](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html)\n- [DynamoDB Best Practices](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices.html)","author":"@itsmostafa","ownerProfile":null,"authorContacts":null,"sourceUrl":"https://github.com/itsmostafa/aws-agent-skills/tree/main/skills/dynamodb","license":"MIT","category":"writing","lang":"en","tokens":2405,"stars":0,"calls30d":2,"claimed":false,"visibility":"public","origin":"crawler","version":"0.1.0","createdAt":"2026-08-22","updatedAt":"2026-08-22","files":[{"path":"query-patterns.md","size":9266,"sha256":"19c2e603e052f4e88e8c3dd7d4c18389a446034e865ba31d69654310787f1791"}],"requires":{"mcp":[],"tools":[]},"safety":{"flags":[],"scannedAt":"2026-08-22","hasScripts":false,"networkEndpoints":["boto3.amazonaws.com","docs.aws.amazon.com"]}}