ทำความเข้าใจกับขีด จำกัด ขนาดของเอกสาร MongoDB BSON


153

จาก MongoDB คำแนะนำการแตกหัก:

เอกสารที่มีขนาดใหญ่กว่า 4MB (เมื่อแปลงเป็น BSON) ไม่สามารถบันทึกลงในฐานข้อมูล นี่เป็นข้อ จำกัด ที่ค่อนข้าง จำกัด (และอาจเพิ่มขึ้นในอนาคต) เป็นส่วนใหญ่เพื่อป้องกันการออกแบบสคีมาที่ไม่ดีและให้ประสิทธิภาพที่สอดคล้องกัน

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

สิ่งนี้จะนับรวมเอกสารที่ซ้อนกันด้วยหรือไม่

ถ้าฉันต้องการเอกสารที่ตรวจสอบการเปลี่ยนแปลงค่า (ในที่สุดจะเติบโตเกินขีด จำกัด 4MB)

หวังว่าจะมีคนอธิบายเรื่องนี้อย่างถูกต้อง

ฉันเพิ่งเริ่มอ่านเกี่ยวกับ MongoDB (ฐานข้อมูล nosql แรกที่ฉันเรียนรู้)

ขอบคุณ.


5
ฉันคิดว่าคำถามควรชี้แจงว่านี่เป็นข้อ จำกัด ของขนาดเอกสาร MongoDB ที่จัดเก็บและไม่ใช่รูปแบบ BSON
alexpopescu

2
แม้ว่าฉันเพิ่งลองบันทึกเอกสารขนาดใหญ่ที่เกินกว่า 4MB เพื่อรับข้อความ "BSON :: InvalidDocument: เอกสารใหญ่เกินไป: เอกสาร BSON ถูก จำกัด ที่ 4194304 ไบต์" หากเป็นเช่นนั้นจะเป็นการหลอกลวงในคำเตือน / ข้อความแสดงข้อผิดพลาดหรือไม่
Nik So

18
คุณสามารถค้นหาขนาดเอกสารสูงสุด BSON ของคุณได้อย่างง่ายดายด้วยdb.isMaster().maxBsonObjectSize/(1024*1024)+' MB'คำสั่งในmongoเชลล์
AhmetB - Google

5
อะไรคือจุดประสงค์ของ schemaless nosql ที่คุณไม่สามารถถ่ายโอนเร็กคอร์ดที่มากกว่า 16 mb และสร้าง crud operation ไว้ด้านบน!
Rizwan Patel

ฉันคิดว่าคำพูดเริ่มต้นบอกว่ามันทั้งหมด ... มีการ จำกัด เพื่อป้องกันการออกแบบสคีมาที่ไม่ดี ตัวอย่างเช่นหากคุณมีโพสต์ที่มีความคิดเห็นมากมายคุณจะต้องมีการรวบรวมรายการบล็อกและการรวบรวมความคิดเห็นหรือการรวบรวมการเปลี่ยนแปลง การออกแบบของ mongo / nosql ช่วยให้สิ่งต่าง ๆ ขนาดใหญ่เป็นเครือข่ายของเอกสาร แต่นักพัฒนาจำเป็นต้องแบ่งออกเป็นส่วนที่เหมาะสม หากไม่มีการตั้งค่าขีด จำกัด ขนาดปัญหาอื่น ๆ จะเกิดขึ้น ฉันคิดว่าขีด จำกัด 4mb นั้นใช้ได้ 16mb เยี่ยมมาก! แต่ถ้าฉันเขียนเอกสารขนาด 16mb นั่นเป็นเงื่อนงำที่ว่ามีบางอย่างผิดปกติกับการออกแบบ
ขนตา

คำตอบ:


126

ก่อนอื่นสิ่งนี้กำลังถูกยกระดับในรุ่นถัดไป8MBหรือ16MB... แต่ฉันคิดว่าจะนำเสนอในมุมมองของเอเลียตจาก 10gen (ผู้พัฒนา MongoDB) ทำให้ดีที่สุด:

แก้ไข: ขนาดได้รับการ'ยก' อย่างเป็นทางการเป็น16MB

ดังนั้นในตัวอย่างบล็อกของคุณ 4MB นั้นเป็นจำนวนมาก .. ตัวอย่างเช่นข้อความที่ไม่มีการบีบอัดแบบเต็มของ "War of the Worlds" มีเพียง 364k (html): http://www.gutenberg.org/etext/36

หากการโพสต์บล็อกของคุณนั้นยาวมากพร้อมกับความคิดเห็นมากมายฉันจะไม่อ่าน :)

สำหรับ trackbacks หากคุณทุ่มเท 1MB ไปคุณสามารถมีมากกว่า 10k (อาจใกล้ถึง 20k)

ดังนั้นยกเว้นสถานการณ์ที่แปลกประหลาดอย่างแท้จริงมันจะใช้งานได้ดี และในกรณียกเว้นหรือสแปมฉันไม่คิดว่าคุณต้องการวัตถุขนาด 20mb อยู่ดี ฉันคิดว่าการกำหนด trackbacks เป็น 15k หรือมากกว่านั้นสมเหตุสมผลมากไม่ว่าจะเป็นเรื่องอะไรสำหรับการแสดง หรืออย่างน้อยปลอกพิเศษถ้ามันเคยเกิดขึ้น

-Eliot

ฉันคิดว่าคุณจะกดยากที่จะถึงขีด จำกัด ... และเมื่อเวลาผ่านไปถ้าคุณอัพเกรด ... คุณจะต้องกังวลน้อยลง

จุดหลักของข้อ จำกัด คือคุณไม่ต้องใช้ RAM ทั้งหมดในเซิร์ฟเวอร์ของคุณ (เนื่องจากคุณจำเป็นต้องโหลดMBเอกสารทั้งหมดลงใน RAM เมื่อคุณทำการค้นหา)

ดังนั้นขีด จำกัด คือ RAM บางส่วนที่สามารถใช้งานได้ปกติบนระบบทั่วไป ... ซึ่งจะเพิ่มขึ้นทุกปี

หมายเหตุเกี่ยวกับการจัดเก็บไฟล์ใน MongoDB

หากคุณต้องการจัดเก็บเอกสาร (หรือไฟล์) ที่มีขนาดใหญ่กว่าที่16MBคุณสามารถใช้GridFS APIซึ่งจะแบ่งข้อมูลออกเป็นเซ็กเมนต์โดยอัตโนมัติและสตรีมกลับไปที่คุณ (เพื่อหลีกเลี่ยงปัญหาเรื่องขนาด จำกัด / RAM)

แทนที่จะเก็บไฟล์ไว้ในเอกสารเดียว GridFS แบ่งไฟล์ออกเป็นส่วน ๆ หรือชิ้นส่วนและเก็บแต่ละอันเป็นเอกสารแยกต่างหาก

GridFS ใช้สองคอลเลกชันในการจัดเก็บไฟล์ คอลเลกชันหนึ่งเก็บส่วนไฟล์และเมทาดาทาไฟล์เก็บอื่น ๆ

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


2
มันยอดเยี่ยมมากที่คุณมี RAM เพียงพอสำหรับฐานข้อมูลทั้งหมดของคุณ ... โดยปกติแล้ว "ชุดการทำงาน" อยู่ใน RAM ไม่ใช่ฐานข้อมูลทั้งหมด (เช่นในกรณีของฉันฉันมีฐานข้อมูลมากกว่าหนึ่ง GB ซึ่งถ้าเพิ่มทั้งหมดแล้วจะเกิน RAM ของฉัน แต่ก็ไม่เป็นไรเพราะชุดการทำงานนั้นเล็กกว่ามาก) นอกจากนี้หากไม่มีข้อ จำกัด คุณอาจโหลดเอกสาร 800MB ไปที่ RAM พร้อมคิวรีหนึ่งแบบสอบถามและเอกสาร 400k อีกชุดหนึ่งทำให้สมดุล RAM ของคุณยากขึ้นเล็กน้อยและอื่น ๆ ดังนั้น "จำกัด " คือบางส่วนของ RAM เซิร์ฟเวอร์ทั่วไป (ซึ่งจะเพิ่มขึ้นเมื่อเวลาผ่านไป) mongodb.org/display/DOCS/Checking+Server+Memory+Usage
Justin Jenkins

3
มันยอดเยี่ยมมากที่คุณสามารถเก็บทุกอย่างไว้ใน RAM แต่พิจารณาประสิทธิภาพและสำนวนบล็อก เห็นได้ชัดว่าคุณต้องการโพสต์ในหน่วยความจำถ้าอ่าน แต่คุณต้องการให้มีความคิดเห็น 10 หน้าเพื่อให้โพสต์บล็อกอยู่ในความทรงจำเมื่อคนส่วนใหญ่ไม่เคยอ่านหน้าแรกหรือไม่ แน่นอนว่าคุณสามารถทำได้และถ้าฐานข้อมูลของคุณมีขนาดเล็กพอที่จะสามารถพอดีกับหน่วยความจำแล้วไม่มีปัญหา แต่ในแง่ของประสิทธิภาพที่บริสุทธิ์คุณไม่ต้องการบิตไร้ประโยชน์ที่จะใช้พื้นที่หน่วยความจำหากคุณสามารถหลีกเลี่ยงได้ (และนั่นก็เพื่อ RDBMS เช่นกัน)
AlexGad

50
พระเยซูแสนหวานอาร์กิวเมนต์ของ Mongo คือ "16 MB น่าจะเพียงพอสำหรับทุกคน"? มันไม่เหมือนที่เคยพิสูจน์ว่าไม่ถูกต้องในอดีต
Robert Christ

2
นี่มันแย่เกินไปสำหรับฉัน Mongo น่าจะมีประโยชน์สำหรับข้อมูลขนาดใหญ่ไม่มีข้อ จำกัด เช่นนั้น ในโครงการของฉันฉันต้องรวมและทวีตกลุ่มที่เกี่ยวข้องกับหัวข้อที่ได้รับความนิยมเหมือนกันและนี่อาจจบลงในมากกว่า 20000 ทวีตเป็นระยะเวลา 20 ชั่วโมง (และอาจเป็นไปได้ว่าจะมีแนวโน้มยาวนานกว่า 20 ชั่วโมงใน db ของฉัน) การมีทวีตจำนวนมากและจัดเก็บข้อความของพวกเขาในเวลาเดียวกันนั้นได้ทำลายล้างและหลังจากจัดกลุ่มแนวโน้มเล็ก ๆ น้อย ๆ มันก็จบลงด้วยข้อยกเว้นเกี่ยวกับแนวโน้มที่ยิ่งใหญ่
Savvas Parastatidis

7
@savvas เหตุใดคุณจึงใส่ทวีตทั้งหมดลงในเอกสารเดียว ใช้หนึ่งเอกสารต่อทวีตใส่หัวข้อแนวโน้มเป็นฟิลด์อื่นในเอกสาร ใส่ดัชนีในฟิลด์หัวข้อนั้นแล้วรวมในฟิลด์นั้นโดยใช้ไพพ์ไลน์ Mongo ต้องใช้การปรับวิธีการทำงานกับ nosql เมื่อคุณปรับวิธีการของคุณและคิดว่าคุณจะพบว่ามันทำงานได้ดีสำหรับกรณีการใช้ข้อมูลขนาดใหญ่จำนวนมาก
schmidlop

32

หลายคนในชุมชนไม่ต้องการ จำกัด คำเตือนเกี่ยวกับประสิทธิภาพการทำงานให้ดูความคิดเห็นนี้เพื่อหาข้อโต้แย้งที่สมเหตุสมผล: https://jira.mongodb.org/browse/SERVER-431?focusedCommentId=22283&page=com.atlassian.jira.plugin system.issuetabpanels: ความคิดเห็น-tabpanel # คิดเห็น-22283

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


5
ฉันเห็นด้วยกับคุณโดยสิ้นเชิงและมันก็เอาชนะจุดประสงค์ของการมีเอกสารฝังตัวอยู่ในขณะนี้เพราะเอกสารที่ฝังส่วนใหญ่จะข้ามขีด จำกัด ได้ง่าย Esp พร้อมอาเรย์ของเอกสารที่อยู่ภายใน
Sharjeel Ahmed

@ marr75 ระบุว่าแก้ไขแล้วตอนนี้แก้ไขแล้วหรือยัง
Mafii

1
ฉันหมายถึงขีด จำกัด เพิ่มขึ้นเป็น 16MB ซึ่งไม่สามารถแก้ไขปัญหา "ปัญหา" ในระยะยาวได้ IMO ขีด จำกัด ควรจะถูกกำจัด
marr75

2
6 ปีด้าย necro ฉันไม่มั่นใจอย่างแน่นอนจากตัวอย่างการใช้งาน / การออกแบบที่ไม่เหมาะสมของคุณ นอกจากนี้ตัวอย่างนั้นดีกว่ามากในการอธิบายว่าทำไมคุณต้องตรวจสอบอินพุตมากกว่าขนาดฐานข้อมูลที่ จำกัด เพียงเอกสารเดียว การทำให้แอปพลิเคชันแยกเอกสารที่ซ้อนกันเป็นเอกสารเดี่ยวในคอลเล็กชันอื่นหรือเริ่มต้นเอกสาร "ความต่อเนื่อง" ใหม่ (โซลูชันที่ฉันใช้หลายครั้งในการทำงานภายในขีด จำกัด นี้) มีผลกระทบต่อประสิทธิภาพการทำงานเล็กน้อย จุดทั้งหมดของฐานข้อมูลเอกสารคือตำแหน่งของข้อมูล
marr75

4
ขอบคุณสำหรับการทำคณิตศาสตร์แบบเดียวกันกับที่เอกสาร mongoDB ทำเพื่อปกป้องการตัดสินใจนี้ แต่กรณีการใช้งานครั้งเดียวและการทดลองทางความคิดของคุณนั้นยังห่างไกลจากข้อสรุป ฉันต้องออกแบบที่ซับซ้อนและซ้ำซ้อนเพื่อแก้ปัญหาข้อเท็จจริงที่ว่ามีการ จำกัด โดยพลการที่จะได้รับผลกระทบจาก mongo (โดยไม่มีรายการซ้อนกันหรือซ้ำซ้อน btw) ตามตรรกะของคุณไม่ควรมีฐานข้อมูลรวมเกินกว่า 16MB เนื่องจากบางข้อความที่กำหนดเองสามารถแสดงโดยใช้ที่เก็บน้อย เห็นได้ชัดว่าโง่
marr75

31

หากต้องการโพสต์คำตอบเพื่อความกระจ่างที่นี่สำหรับผู้ที่เข้ามาที่นี่โดย Google

ขนาดเอกสารรวมทุกอย่างในเอกสารรวมถึงเอกสารย่อยวัตถุที่ซ้อนกันเป็นต้น

ดังนั้นเอกสารของ:

{
    _id:{},
    na: [1,2,3],
    naa: [
        {w:1,v:2,b:[1,2,3]},
        {w:5,b:2,h:[{d:5,g:7},{}]}
    ]
}

มีขนาดสูงสุด 16meg

Sbudocuments และวัตถุที่ซ้อนกันจะถูกนับรวมกับขนาดของเอกสาร


โครงสร้างที่ใหญ่ที่สุดที่เป็นไปได้เพียงอย่างเดียวที่สามารถแสดงใน BSON ได้คือแดกดันและมีขนาดกะทัดรัดที่สุด แม้ว่า MongoDB จะใช้size_tดัชนีอาร์เรย์ 64 บิตภายในข้อ จำกัด ขนาดเอกสาร 16MB จะดีที่สุดสามารถแสดงเอกสารที่มีอาร์เรย์เดียวที่มี NULL สองล้านตัว
รวบรวม

ขอโทษเพิ่มความคิดเห็นที่สองไปยังที่อยู่ / ชี้แจงรายละเอียดที่สำคัญอื่น: เมื่อคุณพูดว่าขนาดของเอกสารรวมถึงทุกอย่างในเอกสารที่ยังรวมถึงปุ่ม เช่นเป็นไบต์ที่สองมีขนาดเล็กกว่า{"f": 1} {"foo": 1}สิ่งนี้สามารถเพิ่มได้อย่างรวดเร็วหากคุณไม่ระวังแม้ว่าการบีบอัดบนดิสก์ในปัจจุบันจะช่วยได้หรือไม่
รวบรวม

6

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

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

ไฟล์ไบนารี <> JSON (เข้ารหัส) <> BSON (เข้ารหัส)

การใส่พา ธ (URL) ไปยังไฟล์ข้อมูลในเอกสารของคุณจะมีประสิทธิภาพมากกว่าและเก็บข้อมูลไว้ในรูปแบบไบนารี

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


1
"มีฐานข้อมูลที่หลากหลายซึ่งมีประสิทธิภาพมากในการจัดเก็บ / ดึงไฟล์ขนาดใหญ่พวกมันถูกเรียกว่าระบบปฏิบัติการ"; ดูblog.mongodb.org/post/183689081/…
redcalx


2

บางทีการจัดเก็บโพสต์บล็อก -> ความคิดเห็นเกี่ยวกับความสัมพันธ์ในฐานข้อมูลที่ไม่เกี่ยวข้องนั้นไม่ใช่การออกแบบที่ดีที่สุดจริงๆ

คุณควรเก็บความคิดเห็นไว้ในชุดสะสมแยกต่างหากในบล็อกโพสต์

[แก้ไข]

ดูความคิดเห็นด้านล่างสำหรับการสนทนาเพิ่มเติม


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

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

3
@Mchel: "บล็อก" ไม่ดี แต่การจัดเก็บความคิดเห็นในคอลเล็กชันแยกต่างหากนั้นไม่ดีด้วยเหตุผลเดียวกัน การโพสต์ที่มีอาร์เรย์ความคิดเห็นนั้นเป็นตัวอย่างของเอกสารฐานข้อมูล
Matt Briggs

6
@SoPeople: การจัดเก็บความคิดเห็นภายในโพสต์เป็นเหมือนตัวอย่างที่เป็นที่ยอมรับของฐานข้อมูลเชิงเอกสาร (เช่นการเก็บข้อความ wiki ทั้งหมดไว้ในเอกสารเดียว) ถ้าฉันจะเขียนดังนั้นมันจะทำงานได้อย่างสมบูรณ์บน MongoDB ไม่มีรายการ SO เหล่านี้จะเกิน 4MB อย่างสมเหตุสมผล Craigslist กำลังทำการย้ายฐานข้อมูลขนาดใหญ่ของประวัติศาสตร์ไปยัง MongoDB พวกเขามีเอกสารเพียงไม่กี่ข้อที่เกินกว่านั้นและผู้พัฒนานำได้แนะนำว่าเอกสารนั้นถูกจับจริง ๆ (ผลของข้อบกพร่องบางอย่าง) อีกครั้ง 4 megs เป็นข้อความหลายเล่ม
Gates VP

3
@Gates VP ฉันเห็นด้วยกับการใช้เครื่องมือข้อความแบบเต็ม ฉันคิดถึงการค้นหาข้อมูลเมตา ถ้าคุณมีเอกสารชุดหนังสือและคุณต้องการค้นหาหนังสือทุกเล่มที่ตีพิมพ์ในปี 2525 หากหนังสือแต่ละเล่มมีข้อความ + 100kb คุณไม่ต้องการถ่ายโอนหลายเมกะไบต์เพื่อแสดงหนังสือ 20 เล่มแรก
mikerobi

0

ตามhttps://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1

หากคุณคาดว่าโพสต์บล็อกอาจเกินขีด จำกัด เอกสาร 16Mb คุณควรแยกข้อคิดเห็นออกเป็นคอลเล็กชันแยกต่างหากและอ้างอิงโพสต์บล็อกจากความคิดเห็นและเข้าร่วมระดับแอปพลิเคชัน

// posts
[
  {
    _id: ObjectID('AAAA'),
    text: 'a post',
    ...
  }
]

// comments
[
  {
    text: 'a comment'
    post: ObjectID('AAAA')
  },
  {
    text: 'another comment'
    post: ObjectID('AAAA')
  }
]
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.