14 สิ่งที่ฉันอยากรู้ก่อนเริ่มต้นกับ MongoDB

การแปลบทความจัดทำขึ้นในวันเริ่มต้นหลักสูตร “ฐานข้อมูลที่ไม่สัมพันธ์กัน”.

14 สิ่งที่ฉันอยากรู้ก่อนเริ่มต้นกับ MongoDB

ไฮไลท์:

  • การพัฒนาสคีมาเป็นสิ่งสำคัญอย่างยิ่งแม้ว่าจะเป็นทางเลือกใน MongoDB ก็ตาม
  • ในทำนองเดียวกัน ดัชนีจะต้องตรงกับสคีมาและรูปแบบการเข้าถึงของคุณ
  • หลีกเลี่ยงการใช้วัตถุขนาดใหญ่และอาร์เรย์ขนาดใหญ่
  • ระมัดระวังกับการตั้งค่า MongoDB โดยเฉพาะอย่างยิ่งในเรื่องความปลอดภัยและความน่าเชื่อถือ
  • MongoDB ไม่มีเครื่องมือเพิ่มประสิทธิภาพคิวรี ดังนั้นคุณต้องระมัดระวังเมื่อดำเนินการคิวรี

ฉันทำงานกับฐานข้อมูลมาเป็นเวลานาน แต่เพิ่งค้นพบ MongoDB เท่านั้น มีบางสิ่งที่ฉันอยากรู้ก่อนที่จะเริ่มทำงาน เมื่อบุคคลมีประสบการณ์ในสาขาใดสาขาหนึ่งแล้ว พวกเขาจะมีความคิดอุปาทานว่าฐานข้อมูลคืออะไรและทำอะไร ด้วยความหวังที่จะทำให้ผู้อื่นเข้าใจได้ง่ายขึ้น ฉันจึงนำเสนอรายการข้อผิดพลาดทั่วไป

การสร้างเซิร์ฟเวอร์ MongoDB โดยไม่มีการตรวจสอบสิทธิ์

น่าเสียดายที่ MongoDB ได้รับการติดตั้งโดยไม่มีการรับรองความถูกต้องตามค่าเริ่มต้น สำหรับเวิร์กสเตชันที่เข้าถึงได้ภายในเครื่อง การปฏิบัตินี้ถือเป็นเรื่องปกติ แต่เนื่องจาก MongoDB เป็นระบบที่มีผู้ใช้หลายคนซึ่งชอบใช้หน่วยความจำจำนวนมาก มันจะดีกว่าถ้าคุณวางไว้บนเซิร์ฟเวอร์ที่มี RAM มากที่สุดเท่าที่จะเป็นไปได้ แม้ว่าคุณจะใช้มันเพื่อการพัฒนาเท่านั้นก็ตาม การติดตั้งบนเซิร์ฟเวอร์ผ่านพอร์ตเริ่มต้นอาจเป็นปัญหาได้ โดยเฉพาะอย่างยิ่งหากสามารถดำเนินการโค้ด Javascript ใดๆ ในคำขอได้ (เช่น $where เพื่อเป็นไอเดียสำหรับ การฉีด).

มีวิธีการรับรองความถูกต้องหลายวิธี แต่วิธีที่ง่ายที่สุดคือการตั้งค่า ID ผู้ใช้/รหัสผ่าน ใช้แนวคิดนี้ในขณะที่คุณนึกถึงการรับรองความถูกต้องแบบแฟนซี LDAP. ในเรื่องความปลอดภัย MongoDB ควรได้รับการอัปเดตอย่างต่อเนื่อง และควรตรวจสอบบันทึกการเข้าถึงโดยไม่ได้รับอนุญาตเสมอ ตัวอย่างเช่น ฉันต้องการเลือกพอร์ตอื่นเป็นพอร์ตเริ่มต้น

อย่าลืมผูกพื้นผิวการโจมตีของคุณกับ MongoDB

รายการตรวจสอบความปลอดภัยของ MongoDB มีเคล็ดลับที่ดีในการลดความเสี่ยงของการบุกรุกเครือข่ายและการรั่วไหลของข้อมูล เป็นเรื่องง่ายที่จะปฏิเสธและบอกว่าเซิร์ฟเวอร์การพัฒนาไม่ต้องการการรักษาความปลอดภัยระดับสูง อย่างไรก็ตาม มันไม่ง่ายอย่างนั้นและสิ่งนี้ใช้ได้กับเซิร์ฟเวอร์ MongoDB ทั้งหมด โดยเฉพาะหากไม่มีเหตุผลอันสมควรที่จะใช้ mapReduce, group หรือ $ที่ไหนคุณต้องปิดการใช้งานรหัสที่กำหนดเองใน JavaScript โดยการเขียนลงในไฟล์กำหนดค่า javascriptEnabled:false. เนื่องจากไฟล์ข้อมูลไม่ได้เข้ารหัสใน MongoDB มาตรฐาน จึงเหมาะสมที่จะเรียกใช้ MongoDB ด้วย ผู้ใช้เฉพาะซึ่งมีสิทธิ์เข้าถึงไฟล์โดยสมบูรณ์ โดยจำกัดการเข้าถึงเท่านั้น และความสามารถในการใช้การควบคุมการเข้าถึงไฟล์ของระบบปฏิบัติการเอง

เกิดข้อผิดพลาดขณะพัฒนาวงจร

MongoDB ไม่ได้ใช้สคีมา แต่ไม่ได้หมายความว่าไม่จำเป็นต้องใช้โครงการนี้ หากคุณเพียงต้องการจัดเก็บเอกสารโดยไม่มีรูปแบบที่สอดคล้องกัน การจัดเก็บเอกสารเหล่านั้นอาจทำได้ง่ายและรวดเร็ว แต่การเรียกคืนในภายหลังอาจเป็นเรื่องยาก ยากจริงๆ.

บทความคลาสสิก "กฎ 6 ข้อสำหรับการออกแบบสคีมา MongoDB" มันคุ้มค่าที่จะอ่านและคุณสมบัติเช่น สำรวจสคีมา ในเครื่องมือของบุคคลที่สาม Studio 3T ควรใช้เพื่อตรวจสอบวงจรเป็นประจำ

อย่าลืมลำดับการจัดเรียง

การลืมลำดับการจัดเรียงอาจทำให้เกิดความยุ่งยากและเสียเวลามากกว่าการกำหนดค่าที่ไม่ถูกต้องอื่นๆ ตามค่าเริ่มต้น MongoBD จะใช้ การเรียงลำดับไบนารี. แต่ไม่น่าจะเป็นประโยชน์กับใครเลย คำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่ คำนึงถึงสำเนียง การเรียงลำดับแบบไบนารี่ถือเป็นเรื่องผิดยุคสมัยที่แปลกประหลาดพร้อมกับลูกปัด คาฟทัน และหนวดหยิกย้อนกลับไปในช่วงทศวรรษที่ 80 ของศตวรรษที่ผ่านมา ตอนนี้การใช้งานของพวกเขายกโทษให้ไม่ได้ ในชีวิตจริง "มอเตอร์ไซค์" ก็เหมือนกับ "มอเตอร์ไซค์" และ “บริเตน” และ “บริเตน” ก็เป็นสถานที่เดียวกัน ตัวพิมพ์เล็กเป็นเพียงตัวพิมพ์ใหญ่ที่เทียบเท่ากับตัวพิมพ์ใหญ่ และอย่าให้ฉันเริ่มเรียงลำดับการออกเสียง เมื่อสร้างฐานข้อมูลใน MongoDB ให้ใช้การจัดเรียงที่ไม่คำนึงถึงสำเนียงและ ลงทะเบียนซึ่งสอดคล้องกับภาษาและ วัฒนธรรมผู้ใช้ระบบ. ซึ่งจะทำให้การค้นหาข้อมูลสตริงง่ายขึ้นมาก

สร้างคอลเลกชันด้วยเอกสารขนาดใหญ่

MongoDB มีความยินดีที่จะโฮสต์เอกสารขนาดใหญ่ถึง 16MB ในคอลเลกชันและ กริดเอฟเอส ออกแบบมาสำหรับเอกสารขนาดใหญ่ที่มีขนาดใหญ่กว่า 16 MB แต่เพียงเพราะสามารถวางเอกสารขนาดใหญ่ไว้ที่นั่นได้ การจัดเก็บจึงไม่ใช่ความคิดที่ดี MongoDB จะทำงานได้ดีที่สุดหากคุณจัดเก็บเอกสารแต่ละฉบับที่มีขนาดไม่กี่กิโลไบต์ โดยถือว่าเอกสารเหล่านั้นเป็นเหมือนแถวในตาราง SQL แบบกว้าง เอกสารขนาดใหญ่จะเป็นต้นตอของปัญหาด้วย ผลผลิต.

การสร้างเอกสารด้วยอาร์เรย์ขนาดใหญ่

เอกสารสามารถมีอาร์เรย์ได้ จะเป็นการดีที่สุดหากจำนวนองค์ประกอบในอาร์เรย์อยู่ห่างจากตัวเลขสี่หลัก หากมีการเพิ่มองค์ประกอบลงในอาร์เรย์บ่อยครั้ง องค์ประกอบนั้นจะเติบโตเร็วกว่าเอกสารที่มีองค์ประกอบนั้นและจะต้องเพิ่มองค์ประกอบนั้นด้วย เคลื่อนไหวซึ่งหมายความว่าจะมีความจำเป็น อัพเดตดัชนีด้วย. เมื่อจัดทำดัชนีเอกสารใหม่ด้วยอาร์เรย์ขนาดใหญ่ ดัชนีมักจะถูกเขียนทับ เนื่องจากมี บันทึกซึ่งเก็บดัชนีไว้ การทำดัชนีใหม่นี้ยังเกิดขึ้นเมื่อเอกสารถูกแทรกหรือลบ

MongoDB มีสิ่งที่เรียกว่า "ปัจจัยการเติม"ซึ่งให้พื้นที่สำหรับการขยายเอกสารเพื่อลดปัญหานี้
คุณอาจคิดว่าคุณสามารถทำได้โดยไม่ต้องสร้างดัชนีอาร์เรย์ น่าเสียดายที่การขาดดัชนีอาจทำให้คุณประสบปัญหาอื่นๆ เนื่องจากเอกสารถูกสแกนตั้งแต่ต้นจนจบ การค้นหาองค์ประกอบที่ส่วนท้ายของอาร์เรย์จึงใช้เวลานานกว่า และการดำเนินการส่วนใหญ่ที่เกี่ยวข้องกับเอกสารดังกล่าวจะเป็น ช้า.

อย่าลืมว่าลำดับขั้นในการรวมมีความสำคัญ

ในระบบฐานข้อมูลที่มีเครื่องมือเพิ่มประสิทธิภาพคิวรี คิวรีที่คุณเขียนคือคำอธิบายถึงสิ่งที่คุณต้องการรับ ไม่ใช่วิธีการรับ กลไกนี้ทำงานโดยการเปรียบเทียบกับการสั่งอาหารในร้านอาหาร โดยปกติแล้วคุณเพียงแค่สั่งอาหาร และไม่ให้คำแนะนำโดยละเอียดแก่พ่อครัว

ใน MongoDB คุณสั่งแม่ครัว ตัวอย่างเช่น คุณต้องแน่ใจว่าข้อมูลผ่านไปได้ reduce เร็วที่สุดเท่าที่จะทำได้ในไปป์ไลน์โดยใช้ $match и $projectและการเรียงลำดับจะเกิดขึ้นหลังจากนั้นเท่านั้น reduceและการค้นหาจะเกิดขึ้นตามลำดับที่คุณต้องการ การมีเครื่องมือเพิ่มประสิทธิภาพคิวรีที่ขจัดงานที่ไม่จำเป็น จัดลำดับขั้นตอนอย่างเหมาะสม และเลือกประเภทการรวมอาจทำให้คุณเสียได้ ด้วย MongoDB คุณสามารถควบคุมได้มากขึ้นโดยเสียความสะดวก

เครื่องมือเช่น สตูดิโอ 3ที จะทำให้การสร้างแบบสอบถามแบบรวมง่ายขึ้น MongoDB. คุณสมบัติตัวแก้ไขการรวมช่วยให้คุณใช้คำสั่งไปป์ไลน์ทีละขั้นตอน และตรวจสอบข้อมูลอินพุตและเอาต์พุตในแต่ละขั้นตอนเพื่อทำให้การแก้ไขจุดบกพร่องง่ายขึ้น

การใช้การบันทึกอย่างรวดเร็ว

อย่าตั้งค่าตัวเลือกการเขียน MongoDB ให้มีความเร็วสูงแต่มีความน่าเชื่อถือต่ำ โหมดนี้ "ไฟล์และลืม" ดูเหมือนเร็วเพราะคำสั่งถูกส่งคืนก่อนที่การเขียนจะเกิดขึ้น หากระบบล่มก่อนที่ข้อมูลจะถูกเขียนลงดิสก์ ระบบจะสูญหายและอยู่ในสถานะที่ไม่สอดคล้องกัน โชคดีที่ MongoDB 64 บิตเปิดใช้งานการบันทึกแล้ว

กลไกการจัดเก็บข้อมูล MMAPv1 และ WiredTiger ใช้การบันทึกเพื่อป้องกันสิ่งนี้ แม้ว่า WiredTiger จะสามารถกู้คืนเป็นความสอดคล้องครั้งล่าสุดได้ จุดควบคุมหากปิดใช้งานการบันทึก

การทำเจอร์นัลช่วยให้แน่ใจว่าฐานข้อมูลอยู่ในสถานะที่สอดคล้องกันหลังการกู้คืน และเก็บรักษาข้อมูลทั้งหมดไว้จนกว่าจะถูกเขียนลงในบันทึก ความถี่ของการบันทึกได้รับการกำหนดค่าโดยใช้พารามิเตอร์ commitIntervalMs.

เพื่อให้แน่ใจว่ารายการต่างๆ ตรวจสอบให้แน่ใจว่าเปิดใช้งานการบันทึกในไฟล์การกำหนดค่าแล้ว (storage.journal.enabled)และความถี่ของการบันทึกจะสอดคล้องกับปริมาณข้อมูลที่คุณสามารถสูญเสียได้

การเรียงลำดับโดยไม่มีดัชนี

เมื่อค้นหาและรวบรวมข้อมูล มักจำเป็นต้องจัดเรียงข้อมูล หวังว่าการดำเนินการนี้จะเสร็จสิ้นในขั้นตอนสุดท้ายหลังจากกรองผลลัพธ์แล้ว เพื่อลดปริมาณข้อมูลที่ถูกจัดเรียง และในกรณีนี้คุณจะต้องมีเพื่อการเรียงลำดับ ดัชนี. คุณสามารถใช้ดัชนีเดี่ยวหรือดัชนีผสมได้

หากไม่มีดัชนีที่เหมาะสม MongoDB จะทำโดยไม่มีดัชนีนั้น ขนาดรวมของเอกสารทั้งหมดมีขีดจำกัดหน่วยความจำอยู่ที่ 32 MB การดำเนินการเรียงลำดับและหาก MongoDB ถึงขีดจำกัดนี้ ก็จะเกิดข้อผิดพลาดหรือส่งคืน ชุดระเบียนว่างเปล่า.

ค้นหาโดยไม่รองรับดัชนี

คำค้นหามีฟังก์ชันคล้ายกับการดำเนินการ JOIN ใน SQL เพื่อให้ทำงานได้ดีที่สุด พวกเขาต้องการดัชนีของค่าของคีย์ที่ใช้เป็นคีย์ต่างประเทศ สิ่งนี้ไม่ชัดเจนเพราะไม่สะท้อนการใช้งาน explain(). ดัชนีดังกล่าวเป็นส่วนเพิ่มเติมจากดัชนีที่เขียนไว้ explain()ซึ่งจะถูกใช้โดยผู้ดำเนินการไปป์ไลน์ $match и $sortเมื่อพบกันที่จุดเริ่มต้นของไปป์ไลน์ ตอนนี้ดัชนีสามารถครอบคลุมทุกขั้นตอนได้แล้ว ไปป์ไลน์การรวมตัว.

การเลือกไม่ใช้การอัปเดตหลายรายการ

วิธี db.collection.update() ใช้เพื่อเปลี่ยนบางส่วนของเอกสารที่มีอยู่หรือทั้งเอกสาร จนถึงการแทนที่ทั้งหมด ขึ้นอยู่กับพารามิเตอร์ที่คุณระบุ update. สิ่งที่ไม่ชัดเจนนักคือจะไม่ประมวลผลเอกสารทั้งหมดในคอลเลกชันเว้นแต่คุณจะตั้งค่าตัวเลือก multi เพื่ออัปเดตเอกสารทั้งหมดที่ตรงตามเกณฑ์คำขอ

อย่าลืมความสำคัญของลำดับคีย์ในตารางแฮช

ใน JSON ออบเจ็กต์ประกอบด้วยคอลเลกชันที่ไม่เรียงลำดับของคู่ชื่อ/ค่าที่มีขนาดตั้งแต่ XNUMX ขึ้นไป โดยที่ name คือสตริง และค่าคือสตริง ตัวเลข บูลีน null อ็อบเจ็กต์ หรืออาร์เรย์

น่าเสียดายที่ BSON ให้ความสำคัญกับลำดับอย่างมากเมื่อทำการค้นหา ใน MongoDB หมายถึงลำดับของคีย์ภายในวัตถุในตัว เรื่องเช่น { firstname: "Phil", surname: "factor" } - สิ่งนี้ไม่เหมือนกับ { { surname: "factor", firstname: "Phil" }. นั่นคือ คุณต้องจัดเก็บลำดับของคู่ชื่อ/ค่าในเอกสารของคุณ หากคุณต้องการให้แน่ใจว่าจะหาได้

อย่าสับสน "โมฆะ" и "ไม่ได้กำหนด"

มูลค่า "ไม่ได้กำหนด" ไม่เคยถูกต้องใน JSON ตาม มาตรฐานอย่างเป็นทางการ JSON (ECMA-404 ส่วนที่ 5) แม้ว่าจะใช้ใน JavaScript ก็ตาม ยิ่งไปกว่านั้น สำหรับ BSON มันล้าสมัยและถูกแปลงเป็น $nullซึ่งไม่ใช่วิธีแก้ปัญหาที่ดีเสมอไป หลีกเลี่ยงการใช้ "ไม่ได้กำหนด" ใน MongoDB.

ใช้ $limit() ไม่มี $sort()

บ่อยครั้งเมื่อคุณพัฒนาใน MongoDB การดูตัวอย่างผลลัพธ์ที่จะถูกส่งกลับจากการสืบค้นหรือการรวมกลุ่มจะเป็นประโยชน์ สำหรับงานนี้คุณจะต้องมี $limit()แต่ไม่ควรอยู่ในโค้ดสุดท้ายเว้นแต่คุณจะใช้มาก่อน $sort. กลไกนี้จำเป็นเพราะไม่เช่นนั้นคุณจะไม่สามารถรับประกันลำดับของผลลัพธ์ได้ และคุณจะไม่สามารถดูข้อมูลได้อย่างน่าเชื่อถือ ที่ด้านบนของผลลัพธ์ คุณจะได้รับรายการต่างๆ ขึ้นอยู่กับการเรียงลำดับ เพื่อให้ทำงานได้อย่างน่าเชื่อถือ การสืบค้นและการรวมกลุ่มจะต้องถูกกำหนดไว้ กล่าวคือ ให้ผลลัพธ์เดียวกันทุกครั้งที่ดำเนินการ รหัสที่มี $limit(), แต่ไม่มี $sortจะไม่ถูกกำหนดไว้และอาจทำให้เกิดข้อผิดพลาดที่ยากต่อการติดตามในภายหลัง

ข้อสรุป

วิธีเดียวที่จะผิดหวังกับ MongoDB คือการเปรียบเทียบโดยตรงกับฐานข้อมูลประเภทอื่น เช่น DBMS หรือมาใช้งานตามความคาดหวังที่แน่นอน มันเหมือนกับการเปรียบเทียบส้มกับส้อม ระบบฐานข้อมูลมีจุดประสงค์เฉพาะ วิธีที่ดีที่สุดคือทำความเข้าใจและชื่นชมความแตกต่างเหล่านี้ด้วยตนเอง คงจะเป็นเรื่องน่าเสียดายที่จะกดดันนักพัฒนา MongoDB ให้ข้ามเส้นทางที่บังคับให้พวกเขาไปตามเส้นทาง DBMS ฉันต้องการเห็นวิธีใหม่ๆ ที่น่าสนใจในการแก้ปัญหาเก่าๆ เช่น การตรวจสอบความสมบูรณ์ของข้อมูล และการสร้างระบบข้อมูลที่ยืดหยุ่นต่อความล้มเหลวและการโจมตีที่เป็นอันตราย

การแนะนำธุรกรรม ACID ของ MongoDB ในเวอร์ชัน 4.0 เป็นตัวอย่างที่ดีในการแนะนำการปรับปรุงที่สำคัญในรูปแบบที่เป็นนวัตกรรม ธุรกรรมหลายเอกสารและหลายใบแจ้งยอดเป็นแบบอะตอมมิกแล้ว นอกจากนี้ยังสามารถปรับเวลาที่ต้องใช้ในการรับการล็อคและยุติธุรกรรมที่ค้างอยู่ รวมถึงเปลี่ยนระดับการแยก

14 สิ่งที่ฉันอยากรู้ก่อนเริ่มต้นกับ MongoDB

อ่านเพิ่มเติม:

ที่มา: will.com

เพิ่มความคิดเห็น