การทำงานกับ MongoDB Single-Collection Pattern ใน Swift
ปรับปรุงประสิทธิภาพของแอปพลิเคชันด้วยการจัดเก็บข้อมูลที่เข้าถึงร่วมกัน สามารถจัดเก็บเอกสารที่เกี่ยวข้องไว้ในคอลเลกชันเดียวกันได้ แม้ว่าเอกสารจะมีรูปร่างต่างกันก็ตาม ดูวิธีการทำงานกับคอลเลกชัน MongoDB แบบโพลีมอร์ฟิคจากแอพ Swift ของคุณ
เป็นสัจพจน์ของ MongoDB ที่คุณจะได้รับประสิทธิภาพและความสามารถในการปรับขนาดได้ดีที่สุดโดยการจัดเก็บข้อมูลที่มีการเข้าถึงร่วมกันมากที่สุด
วิธีที่ง่ายที่สุดและชัดเจนที่สุดในการบรรลุเป้าหมายนี้คือการฝังข้อมูลที่เกี่ยวข้องทั้งหมดลงในเอกสารฉบับเดียว วิธีนี้ใช้ได้ดีในหลายกรณี แต่มีบางสถานการณ์ที่อาจไม่มีประสิทธิภาพ:
- (มาก) ความสัมพันธ์แบบหลายต่อหลายคน สิ่งนี้สามารถนำไปสู่ข้อมูลที่ซ้ำกัน การทำสำเนานี้มักจะยอมรับได้ — ที่เก็บข้อมูลค่อนข้างถูก มันจะเจ็บปวดมากขึ้นเมื่อมีการแก้ไขข้อมูลที่ซ้ำกันบ่อยๆ จากนั้นคุณจะมีค่าใช้จ่ายในการอัปเดตเอกสารทุกฉบับที่ฝังข้อมูลนั้น
- การอ่านเอกสารชิ้นเล็ก ๆ แม้ว่าข้อความค้นหาของคุณจะสนใจเพียงส่วนเล็กๆ ของฟิลด์ในเอกสาร เอกสารทั้งหมดก็จะถูกนำเข้าแคช ซึ่งใช้หน่วยความจำที่สามารถใช้งานได้อย่างมีประสิทธิภาพมากขึ้น
- เอกสารขนาดใหญ่และไม่แน่นอน เมื่อใดก็ตามที่แอปพลิเคชันของคุณทำการเปลี่ยนแปลงเอกสาร เอกสารทั้งหมดจะต้องถูกเขียนกลับไปยังดิสก์ ณ จุดใดจุดหนึ่ง (อาจรวมกับการเปลี่ยนแปลงอื่นๆ ในเอกสารเดียวกัน) WiredTiger เขียนข้อมูลลงดิสก์ในบล็อกขนาด 4 KB หลังการบีบอัด ซึ่งโดยทั่วไปจะแมปกับเอกสารที่ไม่มีการบีบอัดขนาด 16–20 KB หากคุณแก้ไขเอกสารขนาด 20+ KB เพียงเล็กน้อย คุณอาจกำลังใช้ดิสก์ IO โดยเปล่าประโยชน์
รูปแบบคอลเลคชันเดียวมีหลายรูปแบบ แต่สำหรับโพสต์นี้ ฉันเน้นที่ประเด็นสำคัญ:
- ข้อมูลที่เกี่ยวข้องซึ่งสอบถามร่วมกันจะถูกจัดเก็บไว้ในคอลเลกชันเดียวกัน
- เอกสารสามารถมีโครงสร้างที่แตกต่างกันได้
- มีการเพิ่มดัชนีเพื่อให้สามารถดึงข้อมูลทั้งหมดสำหรับการค้นหาที่พบบ่อยของคุณด้วยการค้นหาดัชนีเพียงครั้งเดียว
ฉันจะใช้ Swift แต่หลักการเดียวกันนี้ใช้กับภาษาอื่น หากต้องการดูวิธีการทำเช่น นี้กับ Java/Spring Data โปรดดูที่Single-Collection Designs ใน MongoDB with Spring Data
รันโค้ดตัวอย่าง
ฉันเพิ่งเริ่มใช้MongoDB Swift Driverเป็นครั้งแรก ฉันตัดสินใจสร้างแอปเดสก์ท็อป Mac ที่เรียบง่ายสุด ๆ ที่ให้คุณเรียกดูคอลเลกชันของคุณ (ซึ่งMongoDB Compassทำงาน ได้ดีกว่า มาก ) และแสดงเหตุการณ์ Change Stream ตามเวลาจริง (ซึ่ง Compass ไม่ได้ทำในขณะนี้)
คุณสามารถดาวน์โหลดโค้ดได้จากrepo Swift-Change-Streams เพียงสร้างและเรียกใช้จาก Xcode
ระบุสตริงการเชื่อมต่อของคุณแล้วเรียกดูคอลเลกชันของคุณ เลือกตัวเลือก "เปิดใช้งานสตรีมการเปลี่ยนแปลง" เพื่อแสดงเหตุการณ์การเปลี่ยนแปลงแบบเรียลไทม์
แอปจะแสดงข้อมูลจากคอลเล็กชันส่วนใหญ่เป็นเอกสาร JSON ทั่วไป โดยไม่มีความรู้เรื่องสคีมา มีกรณีพิเศษสำหรับคอลเลกชั่นที่ชื่อว่า “Collection” ในฐานข้อมูลที่ชื่อว่า “Single” — เราจะมาดูกันต่อไป
ข้อมูลตัวอย่าง
คอลเลกชัน Simple.Collection จำเป็นต้องมีเอกสารเหล่านี้ (หรือที่คล้ายกัน):
ข้อมูลนี้แสดงตะกร้าสินค้าที่มี_id"basket1" มีสองรายการที่เกี่ยวข้องกับbasket1 - basket1-item1และ basket1-item2ข้อความค้นหาเดียวจะดึงเอกสารทั้งสามรายการสำหรับตะกร้า (ค้นหาเอกสารทั้งหมดที่_idขึ้นต้นด้วย "basket1") มีดัชนีอยู่ใน_idแอตทริบิวต์เสมอ และดัชนีนั้นจะถูกใช้
โปรดทราบว่าข้อมูลทั้งหมดสำหรับตะกร้าในชุดข้อมูลนี้มีขนาดเล็กมาก — ต่ำกว่าเกณฑ์ 16–20K — ดังนั้นในตัวอย่างในชีวิตจริง ผมขอแนะนำให้ฝังทุกอย่างไว้ในเอกสารเดียวแทน รูปแบบคอลเลกชันเดียวจะเหมาะสมกว่าหากมีรายการโฆษณาจำนวนมาก และแต่ละรายการมีขนาดใหญ่ (เช่น หากฝังภาพขนาดย่อหลายภาพ)
เอกสารแต่ละฉบับยังมีdocTypeแอตทริบิวต์เพื่อระบุว่าเอกสารอ้างอิงถึงตัวตะกร้าเอง หรือรายการใดรายการหนึ่งที่เกี่ยวข้องกัน หากแอปพลิเคชันของคุณมีการค้นหาทั่วไปเพื่อดึงเฉพาะตะกร้าหรือเฉพาะรายการที่เกี่ยวข้องกับตะกร้า คุณสามารถเพิ่มดัชนีผสมได้{ _id: 1, docType: 1}:
การใช้งานอื่น ๆ ของdocTypeสนามรวมถึง:
- ข้อความแจ้งที่จะช่วยให้ผู้คนเข้าใจว่าพวกเขากำลังดูอะไรอยู่ในคอลเลกชั่นนี้
- การกรองข้อมูลที่ส่งกลับจากแบบสอบถามไปยังเอกสารบางประเภทจากการรวบรวม
- การกรองประเภทของเอกสารที่รวมอยู่เมื่อใช้ MongoDB Compass เพื่อตรวจสอบสคีมาของคอลเลกชัน
- อนุญาตให้แอปพลิเคชันระบุประเภทของเอกสารที่ได้รับ จากนั้นรหัสแอปพลิเคชันสามารถรับไดรเวอร์ MongoDB เพื่อยกเลิกการจัดเรียงเอกสารเป็นวัตถุของคลาสที่ถูกต้อง นี่คือสิ่งที่เราจะดูต่อไป
รหัสสำหรับกำหนดเอกสารdocTypeและแปลงเอกสารเป็นวัตถุของคลาสที่เหมาะสมสามารถพบได้ในCollectionView.swift
CollectionView ดึงเอกสารที่ตรงกันทั้งหมดจาก MongoDB และจัดเก็บไว้ในอาร์เรย์ของBSONDocuments:
แอปพลิเคชันสามารถวนซ้ำแต่ละเอกสารในdocsตรวจสอบdocTypeแอตทริบิวต์ แล้วตัดสินใจว่าจะทำอย่างไรตามค่านั้น:
ถ้าdocType == "basket"โค้ดจะแปลงเอกสารทั่วไปเป็นBasketออบเจกต์และส่งต่อไปยังBasketViewการเรนเดอร์
นี่คือBasketคลาสรวมถึง initializer เพื่อสร้าง a BasketจากBSONDocument:
ในทำนองเดียวกันสำหรับItems:
มุมมองย่อยสามารถใช้แอตทริบิวต์จากวัตถุที่พิมพ์ถูกต้องเพื่อแสดงข้อมูลได้อย่างเหมาะสม:
บทสรุป
รูปแบบคอลเลกชั่นเดียวเป็นวิธีการมอบประสิทธิภาพการอ่านและเขียนเมื่อการฝังหรือรูปแบบการออกแบบอื่นๆไม่เหมาะ
รูปแบบนี้แบ่งการแมป 1–1 ระหว่างคลาสแอปพลิเคชันและคอลเลกชัน MongoDB ที่นักพัฒนาหลายคนอาจคิด โพสต์นี้แสดงวิธีการแก้ไข:
- แยกฟิลด์ docType เดียวจากเอกสาร BSON ที่ส่งคืนโดยไดรเวอร์ MongoDB
- ตรวจสอบค่าของ docType และรับไดรเวอร์ MongoDB เพื่อแมปเอกสาร BSON เข้ากับวัตถุของคลาสที่เหมาะสม
เผยแพร่ครั้งแรกที่https://www.mongodb.com





































![รายการที่เชื่อมโยงคืออะไร? [ส่วนที่ 1]](https://post.nghiatu.com/assets/images/m/max/724/1*Xokk6XOjWyIGCBujkJsCzQ.jpeg)