AWS Documentation · Tiếng Việt

Amazon DynamoDB

Cơ sở dữ liệu NoSQL key-value và document, hiệu năng mili-giây ở mọi quy mô — Tài liệu toàn diện từ kiến trúc đến vận hành

Cập nhật 04/2026
Database · NoSQL
AWS Core Service
01 · Tổng quan

DynamoDB là gì?

Amazon DynamoDB là dịch vụ cơ sở dữ liệu NoSQL được quản lý hoàn toàn (fully managed) bởi AWS, hỗ trợ mô hình dữ liệu key-valuedocument. DynamoDB cung cấp hiệu năng ổn định ở mức mili-giây đơn (single-digit millisecond) bất kể quy mô dữ liệu, với khả năng tự động mở rộng (auto scaling) để xử lý hàng triệu request mỗi giây.

Hiệu năng mili-giây
Độ trễ đọc/ghi ổn định dưới 10ms ở mọi quy mô. Hỗ trợ hàng triệu request/giây.
Fully Managed
Không cần quản lý server, patching, backup. AWS lo toàn bộ hạ tầng.
Auto Scaling
Tự động điều chỉnh throughput theo tải thực tế. Hỗ trợ On-Demand mode.
Global Tables
Replication đa vùng (multi-region) active-active với độ trễ thấp.
Bảo mật toàn diện
Encryption at rest (KMS), IAM fine-grained access, VPC Endpoints.
Tích hợp sâu
Lambda triggers, Streams, DAX cache, AppSync, S3 export và nhiều hơn nữa.

Use Cases phổ biến

  • Gaming: Leaderboard, player sessions, game state — yêu cầu latency cực thấp
  • E-commerce: Shopping cart, product catalog, order history
  • IoT: Lưu trữ dữ liệu sensor, telemetry data với throughput cao
  • Social Media: User profiles, feeds, likes, comments
  • Ad Tech: Real-time bidding, click tracking, impression counting
  • Session Management: Lưu session state cho web/mobile applications
  • Serverless Backend: Kết hợp API Gateway + Lambda + DynamoDB

So sánh DynamoDB vs RDS (Relational Database)

Tiêu chí DynamoDB (NoSQL) RDS (SQL)
Mô hình dữ liệu Key-value / Document (schema-less) Relational (schema-based, tables, rows, columns)
Ngôn ngữ truy vấn PartiQL, API-based (GetItem, Query, Scan) SQL (SELECT, JOIN, GROUP BY...)
Scaling Horizontal (tự động, gần như vô hạn) Vertical (scale up instance) + Read Replicas
Hiệu năng Single-digit ms ở mọi quy mô Phụ thuộc vào query complexity & instance size
JOIN Không hỗ trợ (denormalize data) Hỗ trợ đầy đủ
Transactions Có (giới hạn 100 items, 4MB) Có (ACID đầy đủ)
Quản lý Serverless, fully managed Managed nhưng vẫn cần chọn instance type
Chi phí Pay-per-request hoặc provisioned capacity Pay-per-instance (chạy 24/7)
Phù hợp cho High-scale, low-latency, known access patterns Complex queries, ad-hoc reporting, relationships
Khi nào chọn DynamoDB?
Chọn DynamoDB khi bạn cần: hiệu năng ổn định ở quy mô lớn, access patterns đã biết trước, không cần complex JOIN, và muốn serverless/fully managed. Nếu cần ad-hoc queries phức tạp hoặc nhiều relationships → chọn RDS/Aurora.
02 · Kiến trúc

Kiến trúc DynamoDB

DynamoDB tổ chức dữ liệu theo mô hình Tables → Items → Attributes. Mỗi table yêu cầu một Primary Key duy nhất để định danh từng item.

DynamoDB Data Model Table: Users PK (Partition Key) SK (Sort Key) Attributes USER#001 PROFILE name="Minh", email="minh@ex.com", age=28 USER#001 ORDER#2024-001 total=150000, status="shipped" USER#001 ORDER#2024-002 total=89000, status="pending" USER#002 PROFILE name="Lan", email="lan@ex.com", age=25 USER#002 ORDER#2024-003 total=250000, status="delivered" Partition Key Sort Key Attributes (schema-less)

Các thành phần chính

Table (Bảng)

Là đơn vị tổ chức dữ liệu cao nhất. Mỗi table chứa nhiều items và yêu cầu định nghĩa Primary Key khi tạo. Không giới hạn số lượng items trong table.

Item (Bản ghi)

Tương đương một "row" trong SQL. Mỗi item là một tập hợp các attributes. Kích thước tối đa của một item là 400 KB.

Attribute (Thuộc tính)

Tương đương "column" trong SQL, nhưng DynamoDB là schema-less — mỗi item có thể có các attributes khác nhau (trừ Primary Key bắt buộc). Hỗ trợ các kiểu dữ liệu: String, Number, Binary, Boolean, Null, List, Map, Set.

Primary Key — Chìa khóa chính

DynamoDB hỗ trợ 2 loại Primary Key:

Simple Primary Key (Partition Key only)
  • Chỉ có Partition Key (PK)
  • PK phải unique cho mỗi item
  • Ví dụ: userId = "USER#001"
  • Phù hợp khi mỗi entity chỉ có 1 record
Composite Primary Key (PK + SK)
  • Gồm Partition Key + Sort Key (SK)
  • Tổ hợp PK+SK phải unique
  • Ví dụ: PK=USER#001, SK=ORDER#2024-001
  • Phù hợp cho one-to-many relationships
Quan trọng
Partition Key quyết định partition nào sẽ lưu item. Thiết kế PK kém sẽ gây hot partition — một partition nhận quá nhiều traffic trong khi các partition khác rảnh rỗi, dẫn đến throttling.

Cách DynamoDB phân phối dữ liệu

DynamoDB sử dụng consistent hashing trên Partition Key để phân phối items vào các partition vật lý. Mỗi partition có giới hạn:

  • 10 GB dung lượng lưu trữ
  • 3,000 RCU (Read Capacity Units) hoặc 1,000 WCU (Write Capacity Units)

Khi vượt giới hạn, DynamoDB tự động split partition. Tuy nhiên, throughput không được chia đều nếu access pattern không đồng đều.

03 · Capacity Modes

Capacity Modes — Chế độ dung lượng

DynamoDB cung cấp 2 chế độ tính phí và quản lý throughput: ProvisionedOn-Demand. Bạn có thể chuyển đổi giữa 2 mode mỗi 24 giờ.

Provisioned Mode
  • Bạn chỉ định trước số RCU/WCU cần thiết
  • Trả phí theo capacity đã provision (dù dùng hay không)
  • Hỗ trợ Auto Scaling để tự điều chỉnh
  • Có thể mua Reserved Capacity (giảm đến 77%)
  • Phù hợp: traffic ổn định, dự đoán được
On-Demand Mode
  • Không cần chỉ định capacity trước
  • Trả phí theo số request thực tế (pay-per-request)
  • Tự động scale lên/xuống ngay lập tức
  • Đắt hơn ~6.5x so với Provisioned (per request)
  • Phù hợp: traffic không dự đoán, spiky workloads

RCU & WCU — Cách tính toán

Read Capacity Unit (RCU)

Loại đọc Công thức Ví dụ (item 6 KB, 10 reads/s)
Strongly Consistent Read 1 RCU = 1 read/s cho item ≤ 4 KB
RCU = ⌈item_size / 4KB⌉ × reads/s
⌈6/4⌉ × 10 = 2 × 10 = 20 RCU
Eventually Consistent Read 1 RCU = 2 reads/s cho item ≤ 4 KB
RCU = ⌈item_size / 4KB⌉ × reads/s / 2
⌈6/4⌉ × 10 / 2 = 2 × 5 = 10 RCU
Transactional Read Tốn gấp 2x Strongly Consistent
RCU = ⌈item_size / 4KB⌉ × reads/s × 2
⌈6/4⌉ × 10 × 2 = 2 × 20 = 40 RCU

Write Capacity Unit (WCU)

Loại ghi Công thức Ví dụ (item 2.5 KB, 5 writes/s)
Standard Write 1 WCU = 1 write/s cho item ≤ 1 KB
WCU = ⌈item_size / 1KB⌉ × writes/s
⌈2.5/1⌉ × 5 = 3 × 5 = 15 WCU
Transactional Write Tốn gấp 2x Standard Write
WCU = ⌈item_size / 1KB⌉ × writes/s × 2
⌈2.5/1⌉ × 5 × 2 = 3 × 10 = 30 WCU
Mẹo thi SAA
Đề thi thường cho bài toán tính RCU/WCU. Nhớ: Eventually Consistent = 1/2 RCU, Transactional = 2x. Luôn làm tròn lên (ceiling) khi chia item size.

Auto Scaling (Provisioned Mode)

Khi dùng Provisioned Mode, bạn nên bật Auto Scaling để DynamoDB tự điều chỉnh RCU/WCU dựa trên CloudWatch metrics:

  • Target Utilization: Mức sử dụng mục tiêu (ví dụ: 70%)
  • Minimum Capacity: Giá trị RCU/WCU tối thiểu
  • Maximum Capacity: Giá trị RCU/WCU tối đa

Auto Scaling sử dụng Application Auto Scaling service và tạo CloudWatch alarms tự động. Lưu ý: scale up nhanh (vài phút) nhưng scale down chậm hơn (15 phút cooldown).

Burst Capacity
DynamoDB dự trữ 300 giây unused capacity cho mỗi partition. Khi traffic đột ngột tăng, burst capacity sẽ được sử dụng trước khi throttling xảy ra. Tuy nhiên, không nên dựa vào burst capacity cho thiết kế hệ thống.
04 · Secondary Indexes

Secondary Indexes — Chỉ mục phụ

Secondary Indexes cho phép bạn truy vấn dữ liệu theo các attributes khác ngoài Primary Key. DynamoDB hỗ trợ 2 loại: Global Secondary Index (GSI)Local Secondary Index (LSI).

Đặc điểm GSI (Global Secondary Index) LSI (Local Secondary Index)
Partition Key Khác với base table (bất kỳ attribute nào) Giống base table
Sort Key Tùy chọn, bất kỳ attribute nào Bắt buộc, khác với base table SK
Thời điểm tạo Bất kỳ lúc nào (sau khi tạo table) Chỉ khi tạo table (không thể thêm sau)
Giới hạn số lượng 20 GSI / table 5 LSI / table
Consistency Chỉ Eventually Consistent Eventually hoặc Strongly Consistent
Capacity Có RCU/WCU riêng (tách biệt base table) Dùng chung RCU/WCU với base table
Size limit Không giới hạn 10 GB per partition key value
GSI vs LSI — Cách hoạt động Base Table PK: userId | SK: orderId GSI: email-index PK: email | SK: createdAt → PK khác, RCU/WCU riêng LSI: status-index PK: userId | SK: status → Cùng PK, SK khác, dùng chung RCU

Projections — Chọn attributes cho Index

Khi tạo index, bạn chọn attributes nào sẽ được "project" (copy) vào index:

  • KEYS_ONLY — Chỉ copy Primary Key của base table + index key. Tiết kiệm storage nhất.
  • INCLUDE — Copy thêm một số attributes cụ thể mà bạn chỉ định.
  • ALL — Copy toàn bộ attributes. Tốn storage nhất nhưng không cần fetch lại base table.
Best Practice cho Index
  • Chỉ tạo GSI khi thực sự cần query pattern mới — mỗi GSI tốn thêm WCU khi write
  • Dùng KEYS_ONLY hoặc INCLUDE thay vì ALL để giảm chi phí storage
  • GSI throttling có thể ảnh hưởng base table — đảm bảo GSI có đủ WCU
  • Cân nhắc dùng sparse index: chỉ items có attribute đó mới xuất hiện trong index
05 · DynamoDB Streams

DynamoDB Streams — Change Data Capture

DynamoDB Streams ghi lại mọi thay đổi (insert, update, delete) trên table theo thứ tự thời gian. Dữ liệu stream được lưu giữ trong 24 giờ và có thể được xử lý bởi Lambda, Kinesis, hoặc ứng dụng tùy chỉnh.

DynamoDB Streams → Lambda Trigger Application PutItem / UpdateItem DynamoDB Table Stream Change records (24h) λ Lambda Analytics Stream records chứa: KEYS_ONLY | NEW_IMAGE | OLD_IMAGE | NEW_AND_OLD_IMAGES

Stream View Types

View Type Nội dung record Use Case
KEYS_ONLY Chỉ Primary Key của item bị thay đổi Trigger nhẹ, chỉ cần biết item nào thay đổi
NEW_IMAGE Toàn bộ item sau khi thay đổi Sync data sang hệ thống khác
OLD_IMAGE Toàn bộ item trước khi thay đổi Audit log, rollback
NEW_AND_OLD_IMAGES Cả trước và sau khi thay đổi So sánh diff, complex event processing

Lambda Trigger với DynamoDB Streams

Đây là pattern phổ biến nhất: Lambda function tự động được invoke khi có thay đổi trong table.

Single-Table Design — E-commerce Scroll / zoom · Mở draw.io ↗
Ưu điểm Single-Table
  • Giảm số lượng API calls (1 Query lấy nhiều entity types)
  • Giảm latency (không cần multiple round-trips)
  • Transactions dễ dàng hơn (cùng table)
  • Ít tables = ít quản lý capacity
Nhược điểm Single-Table
  • Phức tạp hơn khi thiết kế và maintain
  • Khó hiểu cho team mới
  • Cần biết trước tất cả access patterns
  • Khó thay đổi access patterns sau này

2. Partition Key Design — Thiết kế khóa phân vùng

Partition Key tốt phải có high cardinality (nhiều giá trị unique) và uniform distribution (traffic phân bố đều).

PK kém PK tốtLý do
status (active/inactive) userId status chỉ có 2 giá trị → hot partition
date (2024-01-15) userId#date Tất cả writes trong ngày đổ vào 1 partition
country (VN, US, JP) orderId Ít giá trị, traffic không đều giữa các nước
deviceType (iOS/Android) deviceId Chỉ 2-3 giá trị → extreme hot partition

Write Sharding — Kỹ thuật phân tán ghi

Khi PK tự nhiên có low cardinality, thêm random suffix hoặc calculated suffix để phân tán:

Write Sharding Example
# Thay vì PK = "2024-01-15" (hot partition)
# Thêm random suffix: PK = "2024-01-15#3"

import random

def get_sharded_pk(date_str, num_shards=10):
    """Tạo sharded partition key"""
    shard = random.randint(0, num_shards - 1)
    return f"{date_str}#{shard}"

# Write: PK sẽ là "2024-01-15#0", "2024-01-15#1", ..., "2024-01-15#9"
# Read: Cần query tất cả 10 shards rồi merge kết quả
pk = get_sharded_pk("2024-01-15")

# Scatter-Gather pattern cho read
def query_all_shards(date_str, num_shards=10):
    results = []
    for shard in range(num_shards):
        pk = f"{date_str}#{shard}"
        items = dynamodb.query(
            TableName='Events',
            KeyConditionExpression='PK = :pk',
            ExpressionAttributeValues={':pk': {'S': pk}}
        )
        results.extend(items['Items'])
    return results

3. Cost Optimization — Tối ưu chi phí

Chọn đúng Capacity Mode
Traffic ổn định → Provisioned + Auto Scaling + Reserved Capacity (tiết kiệm đến 77%). Traffic spiky → On-Demand.
Giảm Item Size
Dùng tên attribute ngắn (pk thay vì partitionKey). Nén large values. Lưu binary data trên S3.
Tránh Scan
Scan đọc toàn bộ table → cực tốn RCU. Luôn dùng Query với PK. Tạo GSI nếu cần access pattern mới.
Monitor với CloudWatch
Theo dõi ConsumedReadCapacityUnits, ThrottledRequests, SystemErrors. Set alarms cho anomalies.
TTL — Time to Live
Bật TTL để tự động xóa expired items (sessions, logs). Không tốn WCU khi xóa bằng TTL.
Tối ưu GSI
Dùng sparse index, KEYS_ONLY projection. Xóa GSI không dùng. Mỗi GSI = thêm chi phí write.

4. Các Pattern quan trọng khác

  • Optimistic Locking: Dùng ConditionExpression với version number để tránh concurrent update conflicts
  • TTL (Time to Live): Set attribute chứa epoch timestamp → DynamoDB tự xóa item khi hết hạn (miễn phí, không tốn WCU)
  • Sparse Index: Chỉ items có attribute được index mới xuất hiện trong GSI → tiết kiệm storage và RCU
  • Adjacency List: Dùng PK + SK để model graph relationships (many-to-many)
  • Composite Sort Key: Kết hợp nhiều attributes vào SK: STATUS#SHIPPED#2024-01-15 → hỗ trợ begins_with queries
Quy tắc vàng
Xác định access patterns TRƯỚC khi thiết kế table. DynamoDB không phải SQL — bạn không thể query linh hoạt sau khi đã tạo table. Liệt kê tất cả queries cần thiết, rồi thiết kế PK, SK, và GSI để phục vụ từng query.
13 · CLI Cheat Sheet

AWS CLI Cheat Sheet — DynamoDB

Tổng hợp các lệnh AWS CLI thường dùng nhất khi làm việc với DynamoDB.

Quản lý Table

Table Management
# Tạo table với Composite Primary Key (Provisioned mode)
aws dynamodb create-table \
  --table-name Users \
  --attribute-definitions \
    AttributeName=PK,AttributeType=S \
    AttributeName=SK,AttributeType=S \
  --key-schema \
    AttributeName=PK,KeyType=HASH \
    AttributeName=SK,KeyType=RANGE \
  --billing-mode PROVISIONED \
  --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5

# Tạo table On-Demand mode
aws dynamodb create-table \
  --table-name Events \
  --attribute-definitions AttributeName=eventId,AttributeType=S \
  --key-schema AttributeName=eventId,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST

# Liệt kê tables
aws dynamodb list-tables

# Xem thông tin table
aws dynamodb describe-table --table-name Users

# Xóa table
aws dynamodb delete-table --table-name Users

# Chuyển đổi capacity mode
aws dynamodb update-table \
  --table-name Users \
  --billing-mode PAY_PER_REQUEST

CRUD Operations

CRUD — Create, Read, Update, Delete
# PutItem — Tạo/ghi đè item
aws dynamodb put-item \
  --table-name Users \
  --item '{
    "PK": {"S": "USER#001"},
    "SK": {"S": "PROFILE"},
    "name": {"S": "Nguyen Van Minh"},
    "email": {"S": "minh@example.com"},
    "age": {"N": "28"}
  }'

# GetItem — Đọc 1 item (Strongly Consistent)
aws dynamodb get-item \
  --table-name Users \
  --key '{"PK": {"S": "USER#001"}, "SK": {"S": "PROFILE"}}' \
  --consistent-read

# UpdateItem — Cập nhật attributes
aws dynamodb update-item \
  --table-name Users \
  --key '{"PK": {"S": "USER#001"}, "SK": {"S": "PROFILE"}}' \
  --update-expression "SET age = :newAge, updatedAt = :now" \
  --expression-attribute-values '{
    ":newAge": {"N": "29"},
    ":now": {"S": "2024-01-15T10:30:00Z"}
  }'

# DeleteItem — Xóa item
aws dynamodb delete-item \
  --table-name Users \
  --key '{"PK": {"S": "USER#001"}, "SK": {"S": "PROFILE"}}'

# Conditional Write — Chỉ ghi nếu điều kiện thỏa mãn
aws dynamodb put-item \
  --table-name Users \
  --item '{"PK": {"S": "USER#003"}, "SK": {"S": "PROFILE"}, "name": {"S": "Test"}}' \
  --condition-expression "attribute_not_exists(PK)"

Query & Scan

Query & Scan Operations
# Query — Lấy tất cả items của 1 user
aws dynamodb query \
  --table-name Users \
  --key-condition-expression "PK = :pk" \
  --expression-attribute-values '{":pk": {"S": "USER#001"}}'

# Query — Lấy orders của user (SK begins_with)
aws dynamodb query \
  --table-name Users \
  --key-condition-expression "PK = :pk AND begins_with(SK, :sk)" \
  --expression-attribute-values '{
    ":pk": {"S": "USER#001"},
    ":sk": {"S": "ORDER#"}
  }'

# Query với filter (filter sau khi đọc, vẫn tốn RCU)
aws dynamodb query \
  --table-name Users \
  --key-condition-expression "PK = :pk AND begins_with(SK, :sk)" \
  --filter-expression "total > :minTotal" \
  --expression-attribute-values '{
    ":pk": {"S": "USER#001"},
    ":sk": {"S": "ORDER#"},
    ":minTotal": {"N": "100000"}
  }'

# Query trên GSI
aws dynamodb query \
  --table-name Users \
  --index-name email-index \
  --key-condition-expression "email = :email" \
  --expression-attribute-values '{":email": {"S": "minh@example.com"}}'

# Scan — Đọc toàn bộ table (TRÁNH dùng trong production!)
aws dynamodb scan --table-name Users --max-items 10

# Scan với filter
aws dynamodb scan \
  --table-name Users \
  --filter-expression "age > :minAge" \
  --expression-attribute-values '{":minAge": {"N": "25"}}'

Batch Operations

Batch Read & Write
# BatchWriteItem — Ghi nhiều items (tối đa 25 items, 16 MB)
aws dynamodb batch-write-item --request-items '{
  "Users": [
    {
      "PutRequest": {
        "Item": {
          "PK": {"S": "USER#010"},
          "SK": {"S": "PROFILE"},
          "name": {"S": "User 10"}
        }
      }
    },
    {
      "DeleteRequest": {
        "Key": {
          "PK": {"S": "USER#005"},
          "SK": {"S": "PROFILE"}
        }
      }
    }
  ]
}'

# BatchGetItem — Đọc nhiều items (tối đa 100 items, 16 MB)
aws dynamodb batch-get-item --request-items '{
  "Users": {
    "Keys": [
      {"PK": {"S": "USER#001"}, "SK": {"S": "PROFILE"}},
      {"PK": {"S": "USER#002"}, "SK": {"S": "PROFILE"}}
    ],
    "ProjectionExpression": "PK, #n, email",
    "ExpressionAttributeNames": {"#n": "name"}
  }
}'

Backup, Streams & TTL

Backup, Streams, TTL, GSI
# Bật Point-in-Time Recovery
aws dynamodb update-continuous-backups \
  --table-name Users \
  --point-in-time-recovery-specification PointInTimeRecoveryEnabled=true

# Tạo On-Demand Backup
aws dynamodb create-backup \
  --table-name Users \
  --backup-name users-backup-2024-01-15

# Bật DynamoDB Streams
aws dynamodb update-table \
  --table-name Users \
  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES

# Bật TTL
aws dynamodb update-time-to-live \
  --table-name Sessions \
  --time-to-live-specification Enabled=true,AttributeName=expiresAt

# Tạo GSI
aws dynamodb update-table \
  --table-name Users \
  --attribute-definitions AttributeName=email,AttributeType=S \
  --global-secondary-index-updates '[
    {
      "Create": {
        "IndexName": "email-index",
        "KeySchema": [{"AttributeName": "email", "KeyType": "HASH"}],
        "Projection": {"ProjectionType": "ALL"},
        "ProvisionedThroughput": {
          "ReadCapacityUnits": 5,
          "WriteCapacityUnits": 5
        }
      }
    }
  ]'

# Export table to S3
aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:ap-southeast-1:123456789012:table/Users \
  --s3-bucket my-dynamodb-exports \
  --s3-prefix users/ \
  --export-format DYNAMODB_JSON
PartiQL — SQL-like syntax
DynamoDB hỗ trợ PartiQL cho những ai quen SQL:
PartiQL — SQL-compatible queries
# SELECT (Query)
aws dynamodb execute-statement \
  --statement "SELECT * FROM Users WHERE PK='USER#001' AND begins_with(SK, 'ORDER#')"

# INSERT
aws dynamodb execute-statement \
  --statement "INSERT INTO Users VALUE {'PK': 'USER#099', 'SK': 'PROFILE', 'name': 'Test User'}"

# UPDATE
aws dynamodb execute-statement \
  --statement "UPDATE Users SET age=30 WHERE PK='USER#001' AND SK='PROFILE'"

# DELETE
aws dynamodb execute-statement \
  --statement "DELETE FROM Users WHERE PK='USER#099' AND SK='PROFILE'"