อธิบาย Amazon DynamoDB: สร้างระบบที่ปรับขนาดได้
เรียนรู้ว่า Amazon DynamoDB คืออะไร โมเดล NoSQL ทำงานอย่างไร และรูปแบบการออกแบบเชิงปฏิบัติสำหรับระบบที่ปรับขนาดได้และความหน่วงต่ำ

What DynamoDB Is and Why Teams Use It
Amazon DynamoDB is a fully managed NoSQL database service from AWS, designed for applications that need consistently low-latency reads and writes at virtually any scale. “Fully managed” means AWS handles infrastructure work—hardware provisioning, replication, patching, and many operational tasks—so teams can focus on shipping features instead of running database servers.
At its core, DynamoDB stores data as items (rows) inside tables, but each item can have flexible attributes. The data model is best understood as a mix of:
- Key-value: fetch an item quickly by its primary key, much like looking up a record by an ID.
- Document: store nested attributes (maps and lists), similar to JSON, which is useful for related fields without strict schemas.
Teams choose DynamoDB when they want predictable performance and simpler operations for workloads that don’t fit neatly into relational joins. It’s commonly used for microservices (each service owning its data), serverless apps with bursty traffic, and event-driven systems that react to changes in data.
This post walks through the building blocks (tables, keys, and indexes), how to model around access patterns (including single-table design), how scaling and capacity modes work, and practical patterns for streaming changes into an event-driven architecture.
Core Concepts: Tables, Items, and Primary Keys
DynamoDB is organized around a few simple building blocks, but the details matter because they determine how you model data and how fast (and cost-effective) requests will be.
Tables, items, and attributes
A table is the top-level container. Each record in a table is an item (similar to a row), and each item is a set of attributes (similar to columns).
Unlike relational databases, items in the same table don’t need to share the same attributes. One item might have {status, total, customerId}, while another includes {status, shipmentTracking}—DynamoDB doesn’t require a fixed schema.
Primary keys: simple vs. composite
Every item is uniquely identified by a primary key, and DynamoDB supports two types:
- Simple primary key (partition key only): one attribute uniquely identifies each item.
- Composite primary key (partition key + sort key): multiple items can share the same partition key, while the sort key distinguishes them and defines order within that partition.
In practice, composite keys enable “grouped” access patterns like “all orders for a customer, newest first.”
Query vs. scan (high level)
A Query reads items by primary key (or an index key). It targets a specific partition key and can filter by sort key ranges—this is the efficient, preferred path.
A Scan walks the whole table (or index) and then filters. It’s easy to start with, but it’s usually slower and more expensive at scale.
Limits to keep in mind
A few constraints you’ll feel early:
- Max item size: 400 KB.
- Attribute types: scalars (string/number/binary/boolean/null), sets, lists, and maps.
- Key attributes must be scalar (no lists/maps as partition or sort keys).
These fundamentals set up everything that follows: access patterns, indexing choices, and performance characteristics.
DynamoDB’s Data Model: Key-Value and Document
DynamoDB is often described as both a key-value store and a document database. That’s accurate, but it helps to understand what each implies in day-to-day design.
Key-value access vs. document-style items
At its core, you retrieve data by key. Provide the primary key values and DynamoDB returns a single item. That keyed lookup is what delivers predictable, low-latency storage for many workloads.
At the same time, an item can contain nested attributes (maps and lists), which makes it feel like a document database: you can store structured payloads without defining a rigid schema upfront.
Modeling hierarchical JSON-like structures in items
Items map naturally to JSON-like data:
- Maps represent objects (e.g.,
profile.name,profile.address). - Lists represent arrays (e.g., recent actions, tags).
This is a great fit when an entity is usually read as a whole—like a user profile, a shopping cart, or a configuration bundle.
When to denormalize (and why it’s common)
DynamoDB doesn’t support server-side joins. If your app needs to fetch “an order plus its line items plus shipping status” in one read path, you’ll often denormalize: copy some attributes into multiple items, or embed small substructures directly inside an item.
Trade-offs vs. relational normalization
Denormalization increases write complexity and can create update fan-out. The payoff is fewer round trips and faster reads—often the critical path in scalable systems.
Partition Key and Sort Key: Designing for Access Patterns
The fastest DynamoDB queries are the ones you can express as “give me this partition” (and optionally “within this partition, give me this range”). That’s why key choice is primarily about how you read data, not just how you store it.
Partition key: distribution and predictable reads
The partition key determines which physical partition stores an item. DynamoDB hashes this value to spread data and traffic. If many requests concentrate on a small set of partition key values, you can create “hot” partitions and hit throughput limits even if the table is mostly idle.
Good partition keys:
- Have high cardinality (many distinct values)
- Match a frequent access pattern (so reads are direct, not filtered)
- Avoid values that become “popular” (e.g., a constant like
"GLOBAL")
Sort key: range queries and grouped entities
With a sort key, items sharing the same partition key are stored together and ordered by the sort key. This enables efficient:
- Range queries (
BETWEEN,begins_with) - Time-ordered reads (latest-first with reverse scans)
- Entity grouping (multiple item types under one partition key)
A common pattern is composing the sort key, such as TYPE#id or TS#2025-12-22T10:00:00Z, to support multiple query shapes without extra tables.
Mapping common access patterns to keys
- Get by ID:
PK = USER#<id>(simpleGetItem) - List by user:
PK = USER#<id>,SK begins_with ORDER#(orSK = CREATED_AT#...) - Time-series ranges:
PK = DEVICE#<id>,SK = TS#<timestamp>withBETWEENfor time windows
How key choice affects performance and scalability
If your partition key aligns with your highest-volume queries and distributes evenly, you get consistently low-latency reads and writes. If it doesn’t, you’ll compensate with scans, filters, or extra indexes—each adding cost and increasing the risk of hot keys.
Secondary Indexes: GSI and LSI Explained
Secondary indexes give DynamoDB alternate query paths beyond your table’s primary key. Instead of reshaping your base table every time a new access pattern appears, you can add an index that re-keys the same items for a different query.
GSI vs. LSI: what’s the difference?
A Global Secondary Index (GSI) has its own partition key (and optional sort key) that can be completely different from the table’s. It’s “global” because it spans all table partitions and can be added or removed at any time. Use a GSI when you need a new access pattern that doesn’t fit the original key design—for example, querying orders by customerId when the table is keyed by orderId.
A Local Secondary Index (LSI) shares the same partition key as the base table but uses a different sort key. LSIs must be defined at table creation. They’re useful when you want multiple sort orders within the same entity group (same partition key), like fetching a customer’s orders sorted by createdAt vs. status.
Projections: what gets copied into the index
Projection determines which attributes DynamoDB stores in the index:
- KEYS_ONLY: cheapest storage, but you’ll often need an extra read from the base table.
- INCLUDE: copy only the attributes you commonly return.
- ALL: simplest, but can inflate storage and write cost.
Write amplification (the hidden bill)
Every write to the base table can trigger writes to one or more indexes. More GSIs plus wider projections increases write costs and capacity consumption. Plan indexes around stable access patterns, and keep projected attributes minimal when possible.
Capacity Modes and Scaling Behavior
DynamoDB scaling starts with a choice: On-Demand or Provisioned capacity. Both can reach very high throughput, but they behave differently under changing traffic.
On-Demand vs. Provisioned: how to choose
On-Demand is the simplest: you pay per request and DynamoDB automatically accommodates variable load. It’s a good fit for unpredictable traffic, early-stage products, and spiky workloads where you don’t want to manage capacity targets.
Provisioned is capacity planning: you specify (or auto-scale) read and write throughput and get more predictable pricing at steady usage. It’s often cheaper for known, consistent workloads and for teams that can forecast demand.
Read/write capacity in practice
Provisioned throughput is measured in:
- RCUs (Read Capacity Units): roughly one strongly consistent read per second for up to 4 KB (or two eventually consistent reads).
- WCUs (Write Capacity Units): roughly one write per second for up to 1 KB.
Your item size and access pattern determine real cost: larger items, strong consistency, and scans can burn capacity quickly.
Auto scaling basics (and limits)
Auto scaling adjusts provisioned RCUs/WCUs based on utilization targets. It helps with gradual growth and predictable cycles, but it’s not instant. Sudden spikes can still throttle if capacity doesn’t ramp fast enough, and it can’t fix a hot partition key that concentrates traffic on one partition.
DAX: caching for read-heavy workloads
DynamoDB Accelerator (DAX) is an in-memory cache that can reduce read latency and offload repeated reads (e.g., popular product pages, session lookups, leaderboards). It’s most useful when many clients repeatedly request the same items; it won’t help write-heavy patterns, and it doesn’t replace careful key design.
Consistency, Transactions, and Correctness
DynamoDB lets you trade off read guarantees against latency and cost, so it’s important to be explicit about what “correct” means for each operation.
Eventually consistent vs. strongly consistent reads
By default, GetItem and Query use eventually consistent reads: you might briefly see an older value right after a write. This is often fine for feeds, product catalogs, and other read-mostly views.
With strongly consistent reads (an option for reads from the base table in a single region), DynamoDB guarantees you see the latest acknowledged write. Strong consistency costs more read capacity and can increase tail latency, so reserve it for truly critical reads.
When strong consistency matters
Strong consistency is valuable for reads that gate irreversible actions:
- Checking available inventory before confirming an order
- Reading an authorization flag before granting access
- Fetching the current state of a workflow before executing the next step
For counters, the safest approach is typically not “strong read then write,” but an atomic update (e.g., UpdateItem with ADD) so increments aren’t lost.
Transactional reads/writes
DynamoDB transactions (TransactWriteItems, TransactGetItems) provide ACID semantics across up to 25 items. They’re useful when you must update multiple items together—like writing an order and reserving inventory—or enforcing invariants that can’t tolerate intermediate states.
Idempotency for safe retries
Retries are normal in distributed systems. Make writes idempotent so retries don’t duplicate effects:
- Use a client request token (idempotency key) stored with the result
- Enforce uniqueness with
ConditionExpression(e.g., “only create if attribute_not_exists”) - Prefer atomic updates over read-modify-write loops
Correctness in DynamoDB is mostly about choosing the right consistency level and designing operations so retries can’t break your data.
Partitions, Hot Keys, and Traffic Spikes
DynamoDB stores table data across multiple physical partitions. Each partition has finite throughput for reads and writes, plus a limit on how much data it can hold. Your partition key determines where an item lives; if too many requests target the same partition key value (or a small set of values), that partition becomes the bottleneck.
Why hot partitions happen
Hot partitions are usually caused by key choices that concentrate traffic: a “global” partition key like USER#1, TENANT#default, or STATUS#OPEN, or time-ordered patterns where everyone writes to “now” under one partition key.
Symptoms of hot keys and uneven traffic
You’ll typically see:
- Throttling (
ProvisionedThroughputExceededException) for a subset of keys - Elevated and spiky latency for a few access patterns while others remain fast
- CloudWatch metrics showing uneven consumed capacity and sudden bursts
Mitigation techniques
Design for distribution first, then query convenience:
- Key design: ensure high-cardinality partition keys (e.g.,
TENANT#<id>instead of a shared constant). - Write sharding: add a small random or hashed suffix/prefix such as
ORDER#<id>#<shard>to spread writes across N shards, then query across shards when needed. - Time buckets: bucket by hour/day (
METRIC#2025-12-22T10) to prevent “all writes go to the latest item.”
Handling bursty workloads
For unpredictable spikes, on-demand capacity can absorb bursts (within service limits). With provisioned capacity, use auto scaling and implement client-side exponential backoff with jitter on throttles to avoid synchronized retries that amplify the spike.
Data Modeling Patterns for Scalable Systems
DynamoDB data modeling starts from access patterns, not from ER diagrams. You design keys so the queries you need become fast Query operations, while everything else is either avoided or handled asynchronously.
Single-table design (and why teams like it)
“Single-table design” means storing multiple entity types (users, orders, messages) in one table and using consistent key conventions to fetch related data in a single Query. This reduces cross-entity round trips and keeps latency predictable.
A common approach is composite keys:
PKgroups a logical partition (e.g.,USER#123)SKorders items within that group (e.g.,PROFILE,ORDER#2025-12-01,MSG#000123)
This lets you fetch “everything for a user” or “only orders for a user” by choosing a sort-key prefix.
Relationships: adjacency lists and many-to-many
For graph-like relationships, an adjacency list works well: store edges as items.
PK = USER#123,SK = FOLLOWS#USER#456
To support reverse lookups or true many-to-many, add an inverted edge item or project to a GSI, depending on read paths.
Time-series: bucket + sort key + TTL
For events and metrics, avoid unbounded partitions by bucketing:
PK = DEVICE#9#2025-12-22(device + day)SK = TS#1734825600(timestamp)
Use TTL to expire old points automatically, and keep aggregates (hourly/daily rollups) as separate items for fast dashboards.
If you want a deeper refresher on key conventions, see /blog/partition-key-and-sort-key-design.
Streams and Event-Driven Architectures
DynamoDB Streams is DynamoDB’s built-in change data capture (CDC) feed. When enabled on a table, every insert, update, or delete produces a stream record that downstream consumers can react to—without polling the table.
DynamoDB Streams fundamentals
A stream record contains keys and (optionally) the item’s old and/or new image, depending on the stream view type you choose (keys only, new image, old image, both). Records are grouped into shards, which you read sequentially.
Building event-driven workflows
A common setup is DynamoDB Streams → AWS Lambda, where each batch of records triggers a function. Other consumers are possible too (custom consumers, or piping into analytics/logging systems).
Typical workflows include:
- Materialized views: write a denormalized read model table when the source table changes.
- Cache invalidation: expire or refresh items in Redis/ElastiCache after writes.
- Audit logs: append immutable change events to an audit table or external store.
This keeps the primary table optimized for low-latency reads/writes while pushing derived work to asynchronous consumers.
Ordering, retries, and correctness
Streams provide ordered processing per shard (which typically correlates with the partition key), but there is no global ordering across all keys. Delivery is at-least-once, so duplicates can happen.
To handle this safely:
- Make handlers idempotent (e.g., upsert by primary key, use conditional writes, or store processed event IDs).
- Expect retries and partial batch failures; use DLQs/on-failure destinations where possible.
- Keep side effects (emails, payments) behind deduplication or transactional safeguards.
Designed with these guarantees in mind, Streams can turn DynamoDB into a solid backbone for event-driven systems.
Reliability, Backups, and Observability
DynamoDB is designed for high availability by spreading data across multiple Availability Zones within a region. For most teams, the practical reliability wins come from having a clear backup strategy, understanding replication options, and monitoring the right metrics.
Backups: on-demand vs. point-in-time recovery
On-demand backups are manual (or automated) snapshots you take when you want a known restore point—before a migration, after a release, or prior to a big backfill. They’re great for “bookmark” moments.
Point-in-time recovery (PITR) continuously captures changes so you can restore the table to any second within the retention window. PITR is the safety net for accidental deletes, bad deploys, or malformed writes that slip past validation.
Replication and multi-region options
If you need multi-region resilience or low-latency reads near users, Global Tables replicate data across selected regions. They simplify failover planning, but introduce cross-region replication delay and conflict-resolution considerations—so keep write patterns and item ownership clear.
Monitoring essentials
At minimum, alert on:
- Latency (p95/p99) for reads and writes
- Throttled requests and system errors
- Consumed capacity (and headroom vs. provisioned)
These signals usually surface hot-partition issues, insufficient capacity, or unexpected access patterns.
Incident playbooks
For throttling, first identify the access pattern causing it, then mitigate by temporarily switching to on-demand or increasing provisioned capacity, and consider sharding hot keys.
For partial outages or elevated errors, reduce blast radius: disable non-critical traffic, retry with jittered backoff, and fail gracefully (for example, serving cached reads) until the table stabilizes.
Security and Access Control
DynamoDB security is mostly about tightening who can call which API actions, from where, and on what keys. Because tables can hold many entity types (and sometimes many tenants), access control should be designed alongside the data model.
IAM permissions: least privilege by default
Start with identity-based IAM policies that limit actions (for example, dynamodb:GetItem, Query, PutItem) to the minimum set and scope them to specific table ARNs.
For finer control, use dynamodb:LeadingKeys to restrict access by partition key values—useful when a service or tenant should only read/write items in its own keyspace.
Encryption: what to verify
DynamoDB encrypts data at rest by default using AWS owned keys or a customer-managed KMS key. If you have compliance requirements, verify:
- The table is configured with the intended KMS key
- The calling role has the required KMS permissions (and nothing extra)
For encryption in transit, ensure clients use HTTPS (AWS SDKs do by default). If you terminate TLS in a proxy, confirm the hop between the proxy and DynamoDB is still encrypted.
Network controls: reduce exfiltration paths
Use a VPC Gateway Endpoint for DynamoDB so traffic stays on the AWS network and you can apply endpoint policies to constrain access. Pair this with egress controls (NACLs, security groups, and routing) to avoid “anything can reach the public internet” paths.
Multi-tenant design and isolation patterns
For shared tables, include a tenant identifier in the partition key (for example, TENANT#<id>), then enforce tenant isolation with IAM conditions on dynamodb:LeadingKeys.
If you need stronger isolation, consider separate tables per tenant or per environment, and reserve shared-table designs for cases where operational simplicity and cost efficiency outweigh stricter blast-radius requirements.
Cost Optimization for DynamoDB
DynamoDB is often “cheap when you’re precise, expensive when you’re vague.” Costs typically follow your access patterns, so the best optimization work starts by making those patterns explicit.
Know the cost drivers
Your bill is mainly shaped by:
- Reads and writes (RCUs/WCUs in provisioned mode, request units in on-demand)
- Storage (table data plus item size)
- Secondary indexes (each GSI has its own write and storage costs)
- Streams (read requests against stream records and any downstream consumers)
A common surprise: every write to a table is also a write to each affected GSI, so “just one more index” can multiply write cost.
Design keys to avoid waste
Good key design reduces the need for expensive operations. If you frequently reach for Scan, you’re paying to read data you’ll throw away.
Prefer:
Queryby partition key (and optionally sort key conditions)- Narrow projections in your GSIs (project only attributes you truly need)
If an access pattern is rare, consider serving it via a separate table, an ETL job, or a cached read model rather than a permanent GSI.
Control storage with TTL and lifecycle
Use TTL to automatically delete short-lived items (sessions, temporary tokens, intermediate workflow state). This trims storage and can keep indexes smaller over time.
For append-heavy data (events, logs), combine TTL with sort-key designs that let you query “recent only,” so you don’t routinely touch cold history.
Right-size capacity and avoid accidental spikes
In provisioned mode, set conservative baselines and scale with auto scaling based on real metrics. In on-demand mode, watch for inefficient patterns (large items, chatty clients) that drive request volume.
Treat Scan as a last resort—when you truly need full-table processing, schedule it off-peak or run it as a controlled batch with pagination and backoff.
When to Choose DynamoDB (and When Not To)
DynamoDB shines when your application can be expressed as a set of well-defined access patterns and you need consistently low latency at high scale. If you can describe your reads and writes up front (by partition key, sort key, and a small number of indexes), it’s often one of the simplest ways to operate a highly available data store.
Great fits
DynamoDB is a strong choice when you have:
- Predictable queries (fetch user profile, list a user’s orders by time, load a session by ID)
- High write throughput or spiky traffic you don’t want to babysit
- A need for horizontal scaling without managing servers
- Event-driven designs using Streams to trigger downstream work
When to consider alternatives
Look elsewhere if your core requirements include:
- Complex joins across many entities or frequent relationship traversals
- Ad hoc querying and analytics that change weekly (group-bys, exploratory filters)
- Heavy text search and relevance ranking without an external index
Hybrid approaches that work well
Many teams keep DynamoDB for “hot” operational reads and writes, then add:
- S3 + Athena for analytics and historical reporting
- OpenSearch (or similar) for full-text search and faceting
- A cache layer when certain keys are extremely read-heavy
Prototyping note: shorten the path from model to app
If you’re validating access patterns and single-table conventions, speed matters. Teams sometimes prototype the surrounding service and UI in Koder.ai (a vibe-coding platform that builds web, server, and mobile apps from chat) and then iterate on the DynamoDB key design as real query paths emerge. Even if your production backend differs, quick end-to-end prototypes help reveal which queries should be Query operations versus which ones would accidentally become expensive scans.
Quick decision checklist
Validate: (1) your top queries are known and key-based, (2) correctness needs match the consistency model, (3) expected item sizes and growth are understood, and (4) the cost model (on-demand vs. provisioned plus autoscaling) fits your budget.
คำถามที่พบบ่อย
What is DynamoDB, and when is it a good choice?
DynamoDB เป็นบริการฐานข้อมูล NoSQL ที่จัดการให้ทั้งหมดบน AWS ออกแบบมาเพื่อการอ่าน/เขียนที่มีความหน่วงต่ำอย่างต่อเนื่องที่ระดับสเกลสูง ทีมมักเลือกใช้เมื่อสามารถกำหนดรูปแบบการเข้าถึงโดยใช้คีย์ได้ (เช่น ดึงตาม ID, แสดงรายการตามเจ้าของ, คิวรีช่วงเวลา) และต้องการหลีกเลี่ยงการดูแลเซิร์ฟเวอร์ฐานข้อมูล
มันเป็นที่นิยมในแอปแบบไมโครเซอร์วิส แอปเซิร์ฟเลส และระบบที่ขับเคลื่อนด้วยเหตุการณ์
What are tables, items, and attributes in DynamoDB?
ตารางเก็บ items (เหมือนแถว) แต่ละ item เป็นชุดของ attributes (เหมือนคอลัมน์) และสามารถมีข้อมูลซ้อนกันได้
DynamoDB เหมาะเมื่อคำขอปกติต้องการ “เอนทิตีทั้งก้อน” เพราะ items สามารถมี maps และ lists ในลักษณะคล้าย JSON
What’s the difference between a simple primary key and a composite primary key?
คีย์แบบง่ายคือการมีเพียง partition key ที่ระบุ item เดียวได้ ส่วนคีย์แบบประกอบคือ partition key + sort key ซึ่งอนุญาตให้มีหลายรายการที่ใช้ partition key เดียวกันได้โดยแยกขึ้นตาม sort key และมีการจัดลำดับ
คีย์แบบประกอบช่วยให้ทำรูปแบบเช่น:
- “คำสั่งทั้งหมดของลูกค้า”
- “เหตุการณ์ของอุปกรณ์ระหว่างช่วงเวลา”
When should I use Query vs Scan?
ใช้ Query เมื่อคุณสามารถระบุ partition key (และถ้าจำเป็น เงื่อนไข sort key) — นี่เป็นเส้นทางที่เร็วและขยายได้ดี
ใช้ Scan ก็ต่อเมื่อคุณจำเป็นต้องอ่านทั้งตารางจริงๆ เพราะมันจะเดินอ่านทั้งตารางหรือตัวดัชนีแล้วกรองทีหลัง ซึ่งมักจะช้ากว่าและแพงกว่า
ถ้าคุณสแกนบ่อยๆ นั่นเป็นสัญญาณว่าต้องปรับคีย์หรือดัชนี
What are GSIs and LSIs, and how do I choose?
ดัชนีรองให้เส้นทางการสืบค้นทางเลือก
- GSI (Global Secondary Index): ใช้ partition key (และ optional sort key) ที่ต่างจากตารางหลัก ได้ถูกเพิ่มหรือลบทีหลังได้
- LSI (Local Secondary Index): ใช้ partition key เดียวกับตารางหลักแต่มี sort key ต่าง ต้องกำหนดตอนสร้างตาราง
การมีดัชนีเพิ่มจะเพิ่มต้นทุนการเขียนเพราะข้อมูลจะถูกเขียนซ้ำไปยังดัชนี
How do I choose between On-Demand and Provisioned capacity?
เลือก On-Demand หากทราฟฟิกไม่แน่นอน กระโดดๆ หรือไม่อยากจัดการความจุ คุณจะจ่ายตามคำขอ
เลือก Provisioned หากการใช้งานค่อนข้างคงที่และคุณต้องการต้นทุนที่ควบคุมได้มากขึ้น ควรใช้ร่วมกับ auto scaling แต่ต้องรู้ว่ามันไม่ตอบสนองทันทีต่อการพุ่งของทราฟฟิก
What consistency options does DynamoDB offer, and when do they matter?
โดยปกติการอ่านเป็นแบบ eventually consistent ซึ่งหมายถึงคุณอาจเห็นค่าที่เก่ากว่าเล็กน้อยหลังการเขียน
ใช้การอ่านแบบ strongly consistent สำหรับการอ่านที่ต้องเป็นปัจจุบันทันที เช่น การตรวจสอบสินค้าคงคลังก่อนยืนยันคำสั่ง หรือการตรวจสอบสิทธิ์
สำหรับความถูกต้องภายใต้การแข่งขันกัน เข้าต่อควรใช้ atomic updates (เช่น UpdateItem กับ ADD หรือ ConditionExpression) แทนการอ่าน-แก้ไข-เขียน
When should I use DynamoDB transactions?
Transactions (TransactWriteItems, TransactGetItems) ให้การันตีแบบ ACID ครอบคลุมสูงสุด 25 รายการ
ใช้เมื่อคุณต้องอัปเดตรายการหลายชิ้นพร้อมกัน (เช่น สร้างคำสั่งและจองสต็อก) หรือต้องการบังคับ invariant ที่ไม่ยอมให้มีสถานะกึ่งกลาง
ธุรกรรมมีค่าใช้จ่ายและเพิ่มความหน่วง จึงควรสงวนไว้สำหรับโฟลว์ที่จำเป็นจริงๆ
What are hot keys/partitions, and how can I avoid them?
hot partitions เกิดเมื่อคำขอจำนวนมากไปยังค่า partition key เดียวหรือชุดค่าจำนวนน้อย ทำให้เกิดการจำกัดแม้ว่าตารางจะไม่ยุ่งนักก็ตาม
แนวทางลดปัญหา:
- เลือก partition key ที่มี cardinality สูง
- ทำ write sharding (เพิ่ม suffix/prefix แบบสุ่มหรือแฮช)
- ใช้ time buckets สำหรับข้อมูลแบบ time-series
- ใช้ exponential backoff with jitter เมื่อโดน throttle
How do DynamoDB Streams support event-driven architectures?
เปิด DynamoDB Streams เพื่อรับฟีดการเปลี่ยนแปลงเมื่อมีการ insert, update, delete รูปแบบที่พบบ่อยคือ Streams → Lambda เพื่อเรียกใช้งานเบื้องหลัง
ข้อรับประกันสำคัญที่ต้องออกแบบให้รองรับ:
- การจัดลำดับเป็น ต่อ shard (ไม่ใช่ระดับโลก)
- การส่งแบบ at-least-once (อาจเกิดสำเนาได้)
ทำให้ผู้บริโภค idempotent (upsert ตามคีย์, ใช้ conditional writes, หรือติดตาม ID ของเหตุการณ์ที่ประมวลผลแล้ว)