MongoDB BSON 문서 크기 제한 이해


153

MongoDB에서 확실한 가이드 :

4MB보다 큰 문서 (BSON으로 변환시)는 데이터베이스에 저장할 수 없습니다. 이것은 다소 임의적 인 한계입니다 (향후에 제기 될 수 있음). 주로 스키마 설계가 잘못되는 것을 방지하고 일관된 성능을 보장합니다.

이 제한을 이해하지 못합니다. 이는 4MB보다 큰 주석이 많은 블로그 게시물이 포함 된 문서를 단일 문서로 저장할 수 없음을 의미합니까?

또한 이것은 중첩 문서도 계산합니까?

변경 사항을 감사하는 문서를 원한다면 어떻게해야합니까? (결국 4MB를 초과하여 커질 수 있습니다.)

누군가가 이것을 올바르게 설명하기를 바랍니다.

나는 방금 MongoDB (내가 배우고있는 첫 번째 nosql 데이터베이스)에 대해 읽기 시작했다.

감사합니다.


5
나는 이것이 MongoDB 저장 문서 크기의 제한이며 BSON 형식의 제한이 아니라는 것을 분명히해야한다고 생각합니다.
alexpopescu

2
그러나 방금 "BSON :: InvalidDocument : 너무 큰 문서 : BSON 문서는 4194304 바이트로 제한됩니다."라는 메시지를 표시하기 위해 4MB를 초과하는 거대한 문서를 저장하려고했습니다. 이 경우 경고 / 오류 메시지에서 오해의 소지가 있습니까?
Nik So

18
db.isMaster().maxBsonObjectSize/(1024*1024)+' MB'에서 command를 사용 하여 최대 BSON 문서 크기를 쉽게 찾을 수 있습니다 mongo.
AhmetB-Google

5
16MB 이상의 레코드를 덤프 할 수없고 그 위에 crud 작업을 빌드 할 수없는 schemaless nosql의 목적은 무엇입니까?
Rizwan Patel

초기 인용문이 전부라고 생각합니다 ... 스키마 설계가 잘못되는 것을 막기위한 한계가 있습니다. 예를 들어 댓글이 많은 게시물이있는 경우 블로그 항목 모음과 댓글 모음 또는 변경 모음이 필요합니다. mongo / nosql의 디자인은 문서 네트워크와 같은 방대한 크기의 것을 허용하지만 개발자는 이해하기 쉬운 부분으로 나누어야합니다. 크기 제한을 설정하지 않으면 다른 문제가 발생합니다. 4MB 제한이 괜찮다고 생각합니다. 16mb, 좋습니다! 그러나 16MB 문서를 작성하는 경우 디자인에 다른 문제가 있다는 단서입니다.
속눈썹

답변:


126

우선, 이것은 실제로 다음 버전에서 8MB또는 16MB... 에서 제기되고 있지만, 이것을 관점으로 생각하면 10gen (MongoDB를 개발 한 사람)의 Eliot가 가장 잘 설명합니다.

편집 : 크기는 공식적 으로16MB

예를 들어, "War of the Worlds"의 전체 압축되지 않은 텍스트는 364k (html)입니다. http://www.gutenberg.org/etext/36

귀하의 블로그 게시물이 그처럼 많은 의견을 가진 것이라면, 나는 그것을 읽지 않을 것입니다 :)

트랙백의 경우 1MB를 전용으로 사용하면 10k 이상 (아마도 20k에 가깝게)을 가질 수 있습니다.

정말 기괴한 상황을 제외하고는 잘 작동합니다. 예외적 인 경우 나 스팸의 경우, 어쨌든 20MB 객체를 원한다고 생각하지 않습니다. 트랙백 상한을 15k 정도로 설정하면 성능에 관계없이 많은 의미가 있다고 생각합니다. 또는 적어도 특별한 경우가 발생합니다.

엘리엇

나는 당신이 한계에 도달하기가 매우 어려울 것이라고 생각합니다 ... 그리고 시간이 지남에 따라 업그레이드하면 ... 더 적은 걱정을해야합니다.

제한의 핵심은 MB쿼리 할 때 문서의 모든 RAM을 RAM에로드해야하기 때문에 서버의 모든 RAM을 사용하지 않는 것입니다.

따라서 한도는 일반적인 시스템에서 사용 가능한 일반 RAM의 약 %입니다. 매년 증가하고 있습니다.

MongoDB에 파일 저장시 참고 사항

당신은보다 큰 문서를 저장 (또는 파일)에 필요하면 16MB당신이 사용할 수있는 GridFS의 API 자동 세그먼트로 데이터를 중단하고 다시 그들을 스트리밍 할 것이다 (따라서 크기 제한 / RAM의 문제를 피할 수 있습니다.)

GridFS는 파일을 단일 문서에 저장하는 대신 파일을 부분 또는 청크로 나누고 각 청크를 별도의 문서로 저장합니다.

GridFS는 두 개의 모음을 사용하여 파일을 저장합니다. 한 컬렉션은 파일 청크를 저장하고 다른 컬렉션은 파일 메타 데이터를 저장합니다.

이 방법을 사용하면 SQL 데이터베이스에서와 같이 데이터베이스에 이미지, 파일, 비디오 등을 저장할 수 있습니다. 나는 이것을 사용하여 멀티 기가 바이트 비디오 파일을 저장했습니다.


2
전체 데이터베이스를위한 충분한 RAM을 가지고있는 것이 좋습니다. 일반적으로 "작업 세트"는 전체 데이터베이스가 아닌 RAM에 있습니다 (제 경우에는 모든 추가 된 데이터가 RAM을 초과 할 경우 하나 이상의 x GB 데이터베이스가 있으며, 그러나 작업 세트가 훨씬 작기 때문에 괜찮습니다.) 또한 제한이 없으면 하나의 쿼리가있는 800MB doc를 RAM에로드하고 다른 쿼리가있는 400k doc을로드하여 RAM의 균형을 약간 어렵게 할 수 있습니다. .은 "제한"일반적인 서버의 RAM의 일부 %이다 그래서 (따라서는 시간이 지남에 따라 성장한다.) mongodb.org/display/DOCS/Checking+Server+Memory+Usage
저스틴 젠킨스

3
RAM에 모든 것을 저장할 수 있지만 효율성과 블로그 게시물 관용구를 고려하는 것이 좋습니다. 글이 읽 히면 게시물이 메모리에 있어야합니다. 그러나 대부분의 사람들이 첫 페이지를 읽지 않을 때 블로그 게시물에 대한 10 페이지의 주석이 기억에 남길 원하십니까? 물론, 당신은 그것을 할 수 있고 데이터베이스가 메모리에 모두 들어갈 수있을 정도로 작다면 아무런 문제가 없습니다. 그러나 순수한 효율성 측면에서, 메모리 공간을 피하기 위해 쓸모없는 비트를 사용하지 않으려면 RDBMS도 마찬가지입니다.
AlexGad

50
달콤한 예수, 그래서 몽고의 주장은 "16 MB이면 누구에게나 충분해야한다"는 것입니까? 과거에는 틀린 것으로 판명되지 않았습니다.
Robert Christ

2
이것은 나에게 너무 나빠 보인다. Mongo는 빅 데이터에 유용하지만 그러한 제한은 없습니다. 내 프로젝트에서 동일한 트렌드 주제와 관련된 트윗을 집계하고 그룹화해야하며 이는 20 시간 동안 20000 개 이상의 트윗으로 끝날 수 있습니다 (그리고 더 많은 기간이 지나는 트렌드가있을 수 있습니다) 내 데이터베이스에서 20 시간). 많은 트윗을 가지고 동시에 텍스트를 저장하는 것은 파괴적이며 몇 가지 작은 트렌드를 그룹화 한 후에는 큰 트렌드에 대한 예외로 끝납니다.
Savvas Parastatidis

7
@savvas 왜 모든 트윗을 단일 문서에 넣을까요? 트윗 당 하나의 문서를 사용하고 트 렌딩 주제를 문서의 다른 필드로 놓으십시오. 해당 주제 필드에 색인을 넣은 다음 mongo 파이프 라인을 사용하여 해당 필드에 집계하십시오. 일단 메소드를 조정하고 많은 빅 데이터 사용 사례에 적합하다고 생각하면 nosql로 작업하는 방식을 조정해야합니다.
schmidlop

32

커뮤니티의 많은 사람들이 성능에 대한 경고를 제한하지 않고 선호합니다. https://jira.mongodb.org/browse/SERVER-431?focusedCommentId=22283&page=com.atlassian.jira.plugin. system.issuetabpanels : comment-tabpanel # comment-22283

필자는 초기 개발자가 중요한 "기능"이라고 판단했기 때문에이 문제에 대해 완고한 개발자들입니다. 그들은 누군가가 그것에 대해 의문을 품은 감정이 상하기 때문에 언제라도 그것을 바꾸지 않을 것입니다. 오픈 소스 커뮤니티의 제품에서 벗어나는 성격과 정치의 또 다른 예는 실제로 심각한 문제는 아닙니다.


5
나는 당신에게 전적으로 동의합니다. 또한 대부분의 내장 문서가 이제 한계를 쉽게 넘어 서기 때문에 지금은 내장 문서의 목적을 상실합니다. 내부에 다양한 문서가있는 Esp
Sharjeel Ahmed 8:15의

@ marr75 그것은 지금 고쳐 졌다고, 고쳐 졌습니까?
Mafii

1
"제한"장기 문제를 해결하지 못하는 16MB로 제한이 증가했습니다. IMO 한도를 제거해야합니다.
marr75

2
6 살짜리 실 necro. 나는 당신의 특정 나쁜 유스 케이스 / 디자인 예제에 확신이 없습니다. 또한이 예제는 데이터베이스 단일 문서 크기 제한보다 입력을 확인해야하는 이유를 설명하는 데 훨씬 좋습니다. 응용 프로그램이 중첩 된 문서를 다른 컬렉션의 개별 문서로 분할하거나 새 "연속"문서를 시작하면 (이 제한 내에서 여러 번 사용한 솔루션) 성능에는 거의 영향을 미치지 않지만 코드 복잡성에는 큰 영향을 미쳤습니다. 문서 DB의 전체 요점은 데이터 지역입니다.
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 문서 크기 제한은 최대 200 만 개의 NULL을 포함하는 단일 배열 자체를 포함하는 문서를 나타낼 수 있습니다.
amcgregor

또 다른 중요한 세부 사항을 해결 / 명명하기 위해 두 번째 주석을 추가하는 사과 : 문서 크기에 문서의 모든 내용이 포함되며 도 포함되어 있습니다. 예를 들어 {"f": 1}보다 2 바이트 작습니다 {"foo": 1}. 최신 온 디스크 압축이 도움이 되더라도주의하지 않으면 빠르게 누적 될 수 있습니다.
amcgregor

6

문서 자체에 저장된 큰 파일을 포함하지 않는 한계에 대한 문제는 아직 보지 못했습니다. 대용량 파일을 저장 / 검색 할 때 매우 효율적인 다양한 데이터베이스가 이미 있습니다. 이를 운영 체제라고합니다. 데이터베이스는 운영 체제에서 계층으로 존재합니다. 성능상의 이유로 NoSQL 솔루션을 사용하는 경우 애플리케이션과 데이터 사이에 DB 계층을 배치하여 데이터 액세스에 추가 처리 오버 헤드를 추가하려는 이유는 무엇입니까?

JSON은 텍스트 형식입니다. 따라서 JSON을 통해 데이터에 액세스하는 경우 이진 파일이 uuencode, 16 진 또는 Base 64로 인코딩되어야하기 때문에 이진 파일이있는 경우 특히 그렇습니다. 변환 경로는 다음과 같습니다.

이진 파일 <> JSON (인코딩) <> BSON (인코딩)

문서의 데이터 파일에 대한 경로 (URL)를 저장하고 데이터 자체를 이진으로 유지하는 것이 더 효율적입니다.

알 수없는 길이의 파일을 DB에 실제로 보관하려면 GridFS에 파일을 저장하고 큰 파일에 액세스 할 때 동시성을 종료 할 위험이없는 것이 좋습니다.


1
"대량 파일을 저장 / 검색 할 때 매우 효율적인 다양한 데이터베이스가 이미 있습니다.이를 운영 체제라고합니다."; blog.mongodb.org/post/183689081/…
redcalx


2

비 관계형 데이터베이스에 블로그 게시물-> 주석 관계 를 저장하는 것이 실제로 최상의 디자인은 아닙니다.

어쨌든 블로그 게시물을 위해 별도의 컬렉션에 주석을 저장해야합니다.

[편집하다]

자세한 내용은 아래 의견을 참조하십시오.


15
나는 전혀 동의하지 않습니다. 블로그 게시물 문서의 의견은 MongoDB에서 완벽하게 잘 작성되어야합니다 ... 매우 일반적으로 사용됩니다 (제작에서 두 곳 이상을 사용하고 잘 작동합니다)
Justin Jenkins

2
나는 아마도 내 대답에 지나치게 엄격했을 것입니다. MongoDB 또는 유사한 데이터베이스에 블로그 게시물 및 관련 주석을 저장하는 데 아무런 문제가 없습니다. 사람들은 문서 기반 데이터베이스가 제공하는 능력을 과도하게 사용하는 경향이 있습니다 (가장 급진적 인 예는 모든 데이터를 '블로그'라는 단일 문서에 저장하는 것입니다)
Mchl

3
@Mchel : "블로그"는 좋지 않지만 별도의 컬렉션에 주석을 저장하는 것도 같은 이유로 나쁩니다. 주석 배열이있는 게시물은 문서 DB의 정식 예와 같습니다.
Matt Briggs

6
@SoPeople : 게시물에 주석을 저장하는 것은 문서 지향 DB의 일반적인 예와 같습니다. (하나의 문서 안에 위키 텍스트 전체를 저장하는 것과 같이) SO를 쓰려면 MongoDB에서 완전히 실행됩니다. 이러한 SO 항목 중 어느 것도하려고하지 않습니다 합리적으로 4MB의 초과. Craigslist는 역사를 MongoDB로 대규모 DB 마이그레이션하고 있습니다. 그들은 몇 가지 문서만이 그 한계를 넘게하고 수석 개발자는 문서 자체가 실제로 파열되었다고 제안했습니다 (버그의 결과). 다시 말하지만, 4 메가는 여러 소설 소설입니다.
Gates VP

3
@Gates 부사장은 별도의 전체 텍스트 엔진을 사용하는 것에 동의합니다. 메타 데이터 검색에 대해 생각하고있었습니다. 책 문서 세트가 있고 1982 년에 출판 된 모든 책을 찾으려면 어떻게합니까? 각 책에 + 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.