7. Databases: MongoDB & MySQL
ทำไมหัวข้อนี้สำคัญกับ interview
DB มักเป็น คอขวดและจุดล่ม ของระบบ production. SRE ต้องเข้าใจ indexing, replication และ scaling ในเชิง reliability — ไม่ใช่แค่เขียน query เป็น. คำถามยอดฮิต: "query ช้าจะ debug ยังไง", "replication lag กระทบอะไร", "เลือก SQL หรือ NoSQL เมื่อไร".
มอง DB แบบ SRE: ไม่ได้ถามแค่ "ตอบถูกไหม" แต่ถามว่า "ทนโหลดได้แค่ไหน, ล่มแล้วกู้ยังไง, อ่านได้ค่าที่ consistent แค่ไหน".
Core Concepts
SQL vs NoSQL (มุม reliability)
| แง่มุม | SQL (MySQL) | NoSQL (MongoDB) |
|---|---|---|
| Schema | เข้ม (fixed), มี JOIN | ยืดหยุ่น (document) |
| Consistency | ACID, transaction แข็งแรง | ปรับได้ (write/read concern), เดิมเน้น availability |
| Scale เขียน | vertical + read replica เป็นหลัก | sharding แนวนอนเป็นธรรมชาติ |
| เหมาะกับ | ข้อมูลสัมพันธ์, transaction การเงิน | schema เปลี่ยนบ่อย, ข้อมูลใหญ่กระจาย |
วิธีตอบ 'SQL หรือ NoSQL'
อย่าตอบว่าอันไหน "ดีกว่า". ให้ตอบตาม access pattern + ความต้องการ consistency: ต้อง transaction/relation หลายตาราง → SQL; ต้อง scale เขียนแนวนอน + schema ยืดหยุ่น + รับ eventual consistency ได้ → NoSQL. MongoDB สมัยใหม่ก็มี multi-document transaction แล้ว.
Indexing — ตัวแปรที่กระทบ performance มากที่สุด
Index (มัก B-tree) ทำให้ค้นแบบ O(log n) แทน full scan O(n). แต่มีต้นทุน: เขียนช้าลง
เล็กน้อยและกินพื้นที่.
- Composite index ลำดับสำคัญ: index
(a, b)ใช้ได้กับ query ที่กรองaหรือa,bแต่ ใช้ไม่ได้ถ้ากรองแค่b(กฎ leftmost prefix). - Covering index = index ครอบทุก column ที่ query ต้องการ → ไม่ต้องแตะ table เลย.
- Selectivity: index บน column ที่ค่าซ้ำเยอะ (เช่น boolean) แทบไม่ช่วย.
- ใช้
EXPLAINดูว่า query ใช้ index หรือทำ full scan.
# MySQL: ดู execution plan
EXPLAIN SELECT * FROM orders WHERE user_id = 42 AND status = 'paid';
# มองหา: type=ref/range (ดี) vs type=ALL (full scan = แย่), key=ที่ใช้, rows=ประเมินแถว# MongoDB: สร้าง index และดู plan
db.orders.createIndex({ user_id: 1, status: 1 })
db.orders.find({ user_id: 42, status: "paid" }).explain("executionStats")
# COLLSCAN = ไม่มี index (แย่), IXSCAN = ใช้ indexReplication
MySQL: primary รับ write แล้ว replicate ไป replica (มัก async) — replica ใช้ กระจาย read. ปัญหาหลัก = replication lag: อ่านจาก replica อาจได้ค่าเก่า (stale) เพราะยัง apply ไม่ทัน.
MongoDB replica set: 1 primary (รับ write) + หลาย secondary. ใช้ oplog replicate; ถ้า primary ล่ม จะมีการ election เลือก primary ใหม่อัตโนมัติ (failover).
- Write concern (
w:1vsw:"majority"):majority= ยืนยันว่าเขียนถึง node ส่วนใหญ่ ก่อน ack → ทนการล่มได้ แต่ latency สูงกว่า. - Read preference (
primaryvssecondary): อ่านจาก secondary กระจายโหลดได้ แต่เสี่ยง stale จาก lag.
กับดักที่ถามบ่อย: stale read
กระจาย read ไป replica เพื่อ scale เป็นเรื่องดี — แต่ถ้าโค้ดสมมติว่าอ่านได้ค่าที่
เพิ่งเขียน (read-your-writes) จาก replica จะเจอ bug จาก replication lag เช่น สร้าง
order เสร็จแล้ว query ไม่เจอ. ทางแก้: อ่าน critical path จาก primary หรือใช้
w:majority + read concern ที่เหมาะสม.
Scaling & Bottlenecks
- Vertical (เครื่องใหญ่ขึ้น) ง่ายแต่มีเพดาน; Horizontal (read replica / sharding) ยากกว่าแต่ scale ได้ไกล.
- Sharding (MongoDB): กระจายข้อมูลตาม shard key. เลือก key ผิด (cardinality ต่ำ / monotonic เช่น timestamp) → hot shard (โหลดกองที่ shard เดียว).
- Connection pooling: DB รับ connection ได้จำกัด — แอปหลายตัวเปิด connection ตรงเยอะ ๆ ทำ DB ล่มได้. ใช้ pool / proxy.
- N+1 query: loop ยิง query ทีละแถวแทน JOIN/batch เดียว → ช้ามากภายใต้โหลด.
เชื่อมกับ AWS / Cloud ที่คุณรู้อยู่แล้ว
| แนวคิด | บริการ AWS |
|---|---|
| MySQL managed | Amazon RDS (MySQL) / Aurora MySQL |
| High availability (failover) | RDS Multi-AZ (standby ใน AZ อื่น, auto failover) |
| Scale read | RDS Read Replicas (อ่านกระจาย, มี replica lag metric) |
| MongoDB managed | Amazon DocumentDB (หรือ MongoDB Atlas) |
| NoSQL key-value/sharding | DynamoDB (partition key ≈ shard key) |
| Connection pooling | RDS Proxy (ลด connection storm ตอน scale/failover) |
| Backup / PITR | RDS automated backups + point-in-time recovery |
จุดที่ถามบ่อยบน AWS: Multi-AZ ≠ Read Replica
Multi-AZ = HA/failover (standby ไม่รับ traffic จนกว่าจะ failover) — ไม่ใช่ scaling. Read Replica = scaling read (รับ read ได้ แต่ async lag) — ไม่ใช่ HA อัตโนมัติ. สับสน สองอันนี้เป็นข้อพลาดคลาสสิกในห้องสัมภาษณ์.
Diagram — replication & failover (MongoDB replica set)
คำถาม interview ที่เจอบ่อย + แนวคำตอบ
-
"query ช้า จะ debug ยังไง?" → เริ่มที่
EXPLAIN/.explain()ดูว่า full scan (type=ALL / COLLSCAN) ไหม → เพิ่ม/แก้ index (ลำดับ composite, covering) → ดู lock/connection/replica lag ประกอบ → ระวัง N+1. -
"replication lag คืออะไร กระทบยังไง?" → replica apply change ตามหลัง primary → อ่านจาก replica ได้ค่าเก่า. กระทบ read-your-writes, report ที่ต้องแม่น, และ failover (ข้อมูลที่ยัง lag อาจหาย). ลดด้วย network/hardware ที่ดี, semi-sync, หรืออ่าน critical จาก primary.
-
"Multi-AZ ต่างจาก Read Replica ยังไง?" → Multi-AZ = HA/failover (standby ไม่รับ read); Read Replica = scale read (async lag). คนละวัตถุประสงค์.
-
"เลือก shard key ยังไงไม่ให้เกิด hot shard?" → เลือก key ที่ cardinality สูงและกระจายโหลดสม่ำเสมอ; หลีกเลี่ยง monotonic key (timestamp/auto-id) ที่ทำให้ write ใหม่กองที่ shard เดียว. อาจใช้ hashed shard key.
-
"write concern majority มีข้อดี/เสียอะไร?" → ข้อดี: ทนการล่มของ node (ยืนยันถึง majority ก่อน ack → ไม่หายตอน failover). ข้อเสีย: latency สูงขึ้นเพราะรอหลาย node.
Pitfalls — จุดที่ผู้สมัครมักพลาด
ระวังกับดักเหล่านี้
- Composite index ลำดับผิด → query ไม่ใช้ index (ลืมกฎ leftmost prefix).
- อ่านจาก replica แล้วคาดหวัง read-your-writes → เจอ stale จาก lag.
- มองว่า Multi-AZ = scaling → ที่จริงคือ HA เท่านั้น.
- เลือก shard key เป็น timestamp/auto-increment → hot shard.
- ไม่มี connection pooling → connection storm ทำ DB ล่ม (โดยเฉพาะตอน autoscale/failover).
- N+1 query → ดูโอเคตอน dev แต่ระเบิดใต้โหลด.
- สร้าง index มั่วทุก column → เขียนช้าลงและกินพื้นที่โดยไม่จำเป็น.
Quiz ท้ายบท
Quiz ท้ายบท
ตอบแล้ว 0/71.มี composite index (user_id, status) — query ใดจะ 'ไม่' ได้ประโยชน์จาก index นี้?
2.การอ่านจาก read replica แล้วคาดหวังว่าจะเห็นข้อมูลที่เพิ่งเขียนไปที่ primary ทันที มีความเสี่ยงอะไร?
3.ใน RDS ความต่างระหว่าง Multi-AZ กับ Read Replica คือข้อใด?
4.การเลือก shard key เป็น timestamp หรือ auto-increment id มักทำให้เกิดปัญหาใด?
5.จุดเริ่มต้นที่ดีที่สุดในการ debug query ที่ช้าคือข้อใด?
6.ข้อดีหลักของการตั้ง write concern เป็น 'majority' ใน MongoDB คืออะไร?
7.'N+1 query problem' คืออะไร?
Cheat Sheet — อ่านก่อนเข้าห้องสัมภาษณ์
สรุปเร็ว 30 วินาที
- SQL vs NoSQL เลือกตาม access pattern + consistency ไม่ใช่ "อันไหนดีกว่า"
- Index: B-tree
O(log n); composite ใช้ leftmost prefix; ดูด้วยEXPLAIN/.explain()(ALL/COLLSCAN = แย่) - Replication lag → stale read; ระวัง read-your-writes จาก replica
- Multi-AZ = HA/failover (ไม่ scale) · Read Replica = scale read (async lag)
- MongoDB: replica set (primary/secondary/election, oplog), w:majority ทน failover
- Shard key อย่าใช้ monotonic (timestamp/auto-id) → hot shard
- ระวัง N+1, ไม่มี connection pooling (ใช้ RDS Proxy), index มั่วเกิน