| เอกสาร (Document) |
|---|
| sub-document ที่ซ้อนกันอยู่ภายในเอกสารแม่เดียว แทนที่จะแยกเป็นตารางต่างหาก | ความสัมพันธ์แบบ one-to-few ที่ต้องอ่านพร้อมกัน เช่น ออเดอร์กับรายการสินค้า หรือผู้ใช้ที่มีสามที่อยู่ |
| เก็บแค่ id ของฝั่งตรงข้าม ไม่เก็บข้อมูลจริง แล้วดึงมาด้วยการอ่านครั้งที่สองหรือใช้ $lookup | เอนทิตีย่อยที่ใหญ่ ถูกใช้ร่วมกัน หรือถูกอัปเดตแยกจากกัน เช่น ความสัมพันธ์ many-to-many ข้ามคอลเลกชัน |
| เอกสารแม่ฝัง array สั้น ๆ ของลูกไว้ ทั้งชุดจึงพอดีและโหลดมาเป็นเอกสารเดียว | เบอร์โทรหรือ preference ไม่กี่รายการในโปรไฟล์ อ่านครั้งเดียวได้ทั้งแม่และลูก |
| ลูกอยู่ในคอลเลกชันของตัวเอง แต่ละตัวมี parent id หรือไม่ก็ฝั่งแม่เก็บ array ของ id ที่มีขอบเขตจำกัด | ชุดข้อมูลที่ใหญ่หรือเป็นอิสระเกินกว่าจะฝัง ค้นหาลูกด้วย parent id |
| ลูกเป็นผู้เก็บ parent id ฝั่งแม่ไม่เก็บรายชื่อลูกเลยเพราะชุดข้อมูลไม่มีขอบเขตบน | event, log หรือ vote ที่ผูกกับ host หรือผู้ใช้ กรองลูกด้วย parent id แล้วแบ่งหน้า |
| เอกสารของหลายชนิดเอนทิตีใช้คอลเลกชันเดียวกัน แยกกันด้วยฟิลด์ type | comment หรือ notification ที่เกาะกับแม่หลายชนิด แต่ค้นหาด้วยวิธีเดียว |
| แยกเอนทิตีสุดโต่งไม่กี่ตัวออกจากรูปทรงปกติ เพื่อไม่ให้ขนาดหรือปริมาณ traffic ของมันบิดเบือนส่วนที่เหลือ | บัญชีคนดังที่รายชื่อผู้ติดตามหรือตัวนับจะโตเกินขนาดเอกสารปกติ |
| แต่ละรีวิชันคือเอกสารใหม่ที่มี id เดิมและเลขเวอร์ชันที่เพิ่มขึ้น คิวรีเลือกเอาตัวล่าสุด | audit trail และประวัติการแก้ไขที่ยังต้องค้นย้อนรีวิชันเก่าได้ |
| ค่าที่คำนวณได้ถูกคำนวณตอนเขียนแล้วเก็บไว้ข้างข้อมูลที่มันสรุป | ยอดรวม คะแนน rating และ top-N ที่ไม่อยากวิ่ง aggregation ทุกครั้งที่อ่าน |
| Key-value และ wide-column |
|---|
| คำศัพท์ออกแบบของ DynamoDB: รวมหลายชนิดเอนทิตีลงตารางเดียวโดยใช้ partition key และ sort key แบบ overloaded | ดึง item หลากหลายชนิดมาในคิวรีเดียวโดยไม่ต้อง join |
| แอตทริบิวต์คีย์เดียวใช้กับหลายชนิดเอนทิตี กำกับด้วย prefix อย่าง USER# หรือ ORDER# | งานออกแบบ single-table จับกลุ่ม item ที่เกี่ยวข้องไว้ใน partition เดียวแล้วดึงมาในคิวรีเดียว |
| partition key กระจายแถวข้ามโหนด ส่วน sort key จัดลำดับภายในแต่ละ partition | Cassandra และ DynamoDB งาน range scan, log ที่ต้องเรียงตามลำดับ, composite key แบบลำดับชั้น |
| เอาหลายแอตทริบิวต์มาต่อกันเป็น sort key เดียวที่มีตัวคั่น — country#region#city — เพื่อให้ prefix match เดินลงตามลำดับชั้น | โครงสร้างลำดับชั้นและตัวกรองหลายมิติ range query เดียวที่เรียงแล้วแทนการค้น index หลายรอบ |
| จับกลุ่ม event เข้าหน้าต่างเวลาคงที่ — ชั่วโมง วัน เดือน — ใน partition หรือตารางเฉพาะ | metrics, log และ telemetry จาก IoT จำกัดขนาด partition และทิ้งข้อมูลเย็นตามอายุ |
| ทำสำเนาฟิลด์ที่อ่านบ่อยไว้ในหลาย record เพื่อให้คิวรีไม่ต้องวิ่งตาม lookup รอบที่สอง | งานที่อ่านหนักกว่าเขียนมาก ยอมรับ eventual consistency ได้และพื้นที่จัดเก็บถูก |
| secondary index ที่สร้างบนแอตทริบิวต์ที่มีเฉพาะบาง item ตัวที่ไม่มีก็ไม่เข้า index | ทางเข้าถึงแบบสำรอง หา subset แบบ sparse — ออเดอร์ที่ยังเปิด, ของที่ยังไม่ส่ง — โดยไม่ต้อง scan ทั้งตาราง |
| เขียนคิวรีที่ต้องการลงไปก่อนเป็นตัวตั้ง โครงร่างตารางค่อย derive มาจากคิวรี ไม่ใช่จากเอนทิตีหรือ normal form | งานออกแบบ schema ของ Cassandra และ DynamoDB ตารางเดียวต่อกลุ่มคิวรี โมเดลข้อมูลลอกคำถามไปเลย |
| คิวรีต้องกระทบหลาย partition หรือหลายโหนดพร้อมกันเพราะไม่มีคีย์ไหนตรงกับคำถาม | เป็นกลิ่นที่ต้องออกแบบให้หายไป ไม่ใช่เป้าหมาย เปลี่ยนคีย์ของตารางให้คิวรีที่พบบ่อยลง partition เดียว |
| สำเนาถูกผลักไปยัง view ของผู้อ่านแต่ละคนตอนเขียน หรือไม่ก็รวบรวมแล้ว merge ตอนอ่าน | feed และ timeline fan-out ตอนเขียนสำหรับผู้ชมกลุ่มเล็ก ตอนอ่านสำหรับกลุ่มที่ใหญ่มาก |
| ผลลัพธ์คิวรีที่คำนวณไว้ล่วงหน้าแล้วเก็บเป็นตารางของตัวเอง ดูแลให้ทันสมัยตามตารางหลัก | รูปทรงการอ่านแบบอื่นบนเส้นทางเขียนเดียว ตอบคิวรีที่ตารางหลักตอบไม่ได้ |
| กราฟ (Graph) |
|---|
| แต่ละ edge คือแถวหรือ tuple ที่ชี้จากโหนดต้นทางไปยังโหนดปลายทาง | graph และ property store งานค้นแบบ friend-of-friend, routing, ระบบแนะนำ |
| แต่ละความสัมพันธ์เป็นเอกสารในคอลเลกชันของตัวเอง มี id ฝั่ง from กับ to พร้อมแอตทริบิวต์ของลิงก์ | กราฟใน document store แอตทริบิวต์อยู่บนลิงก์เอง — rating, role, timestamp |
| ทุกโหนดเก็บตัวนับฝั่งซ้ายและขวาจากการเดินแบบ depth-first ทั้ง subtree อยู่ในช่วงของแม่ | ต้นไม้ที่อ่านหนัก คิวรี BETWEEN เดียวได้ทั้ง subtree ส่วนการ insert ต้องเรนัมเบอร์การเดินใหม่ |
| ตารางเฉพาะที่บันทึกคู่บรรพบุรุษ-ลูกหลานทุกคู่ รวมถึงโหนดตัวมันเองที่ depth เป็นศูนย์ | คิวรีทั้งกิ่งที่ความลึกเท่าไหร่ก็ได้ join ง่าย แต่จ่ายด้วยพื้นที่จัดเก็บและการดูแลรักษา |
| property graph แปะแอตทริบิวต์แบบ key-value บนโหนดและ edge ส่วน RDF เขียนทุกอย่างเป็น triple แบบ subject-predicate-object | property graph สำหรับ traversal ที่ซับซ้อน (Neo4j) RDF สำหรับ linked open data และการแลกเปลี่ยน ontology |
| เวกเตอร์ (Vector) |
|---|
| array ของ float มิติสูงวางอยู่ข้าง metadata โดยมี index แบบ ANN คอยหาเพื่อนบ้านที่ใกล้ที่สุด | semantic search, การดึงข้อมูล RAG, ระบบแนะนำ และการหาความคล้ายบนเนื้อหาที่ไม่มีโครงสร้าง |
| เอกสารต้นทางถูกตัด — ตามขนาด ตามส่วนซ้อนทับ หรือตามโครงสร้าง — ก่อนที่ชิ้นแต่ละชิ้นจะถูก embed แยกจากกัน | คุณภาพการดึงข้อมูลของ RAG ขนาด chunk แลก precision กับ recall ส่วน overlap ปกป้องประโยคที่ถูกตัด |
| ความคล้ายแบบ dense vector ทำงานคู่กับการจับคู่คีย์เวิร์ด แล้วเอาอันดับสองชุดมา fuse เป็นผลลัพธ์เดียว | คิวรีที่ต้องการทั้งคำตรงตัวและความหมายพร้อมกัน พร้อมตัวกรอง metadata ซ้อนขึ้นไป |