관계형 데이터베이스 배경에서 온 MongoDB를 처음 사용합니다. 나는 약간의 의견에 질문의 구조를 설계 할,하지만 난 의견에 사용할 관계 모르는 : embed
나 reference
?
stackoverflow 와 같은 주석이있는 질문은 다음과 같은 구조를 갖습니다.
Question
title = 'aaa'
content = bbb'
comments = ???
처음에는 embed
다음과 같이 포함 된 주석 ( MongoDB에서 권장되는 것으로 생각합니다 )을 사용하고 싶습니다.
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
분명하지만이 사건에 대해 걱정 합니다. 지정된 의견을 편집하려면 내용과 질문을 어떻게 얻습니까? 더 없다 _id
내가 하나를 찾을 수 없으며, question_ref
내가 그 질문을 찾을 수 있습니다. (저는 초보자가 아니기 때문에 _id
및 없이이 작업을 수행 할 방법이 있는지 모르겠습니다 question_ref
.)
사용 ref
하지 않아야 embed
합니까? 그런 다음 주석을위한 새 컬렉션을 만들어야합니까?
답변
이것은 과학보다 예술입니다. 스키마에 대한 몽고 문서 는 좋은 참고 자료이지만 고려해야 할 사항이 있습니다.
-
가능한 많이 넣어
문서 데이터베이스의 즐거움은 많은 조인을 제거한다는 것입니다. 첫 번째 본능은 가능한 한 단일 문서에 배치해야합니다. MongoDB 문서에는 구조가 있고 해당 구조 내에서 효율적으로 쿼리 할 수 있기 때문에 (필요한 문서의 일부를 취할 수 있으므로 문서 크기는 크게 걱정하지 않아도 됨) 데이터를 즉시 정규화 할 필요가 없습니다. 당신은 SQL에서 할 것입니다. 특히, 상위 문서와 별도로 유용하지 않은 데이터는 동일한 문서의 일부 여야합니다.
-
여러 장소에서 참조 할 수있는 데이터를 자체 컬렉션으로 분리합니다.
이것은 “데이터 일관성”문제이므로 “스토리지 공간”문제는 아닙니다. 많은 레코드가 동일한 데이터를 참조 할 경우 단일 레코드를 업데이트하고 다른 위치에 참조를 유지하는 것이 더 효율적이고 오류가 적습니다.
-
문서 크기 고려 사항
MongoDB는 단일 문서에 4MB (16MB, 1.8) 크기 제한을 적용합니다. GB의 데이터 세계에서는이 소리가 작게 들리지만 30 만 트윗 또는 250 개의 일반적인 스택 오버플로 응답 또는 20 번 깜박임 사진입니다. 반면에, 이것은 일반적인 웹 페이지에 한 번에 제시하고자하는 것보다 훨씬 많은 정보입니다. 먼저 쿼리를보다 쉽게 만드는 방법을 고려하십시오. 대부분의 경우 문서 크기에 대한 우려는 조기 최적화입니다.
-
복잡한 데이터 구조 :
MongoDB는 임의의 깊은 중첩 데이터 구조를 저장할 수 있지만 효율적으로 검색 할 수는 없습니다. 데이터가 트리, 포리스트 또는 그래프를 형성하는 경우 각 노드와 해당 가장자리를 별도의 문서에 효과적으로 저장해야합니다. (이 유형의 데이터를 위해 특별히 설계된 데이터 저장소도 고려해야합니다.)
또한 문서에서 요소의 하위 집합을 반환하는 것이 불가능하다는 것보다 지적되었습니다 . 각 문서의 몇 비트를 골라서 선택해야하는 경우 분리하기가 더 쉬울 것입니다.
-
데이터 일관성
MongoDB는 효율성과 일관성 사이에서 균형을 유지합니다. 규칙은 단일 문서에 대한 변경 사항은 항상 원 자성이지만 여러 문서에 대한 업데이트 는 원 자성으로 간주해서는 안됩니다. 서버에서 레코드를 “잠그는”방법도 없습니다 (예 : “잠금”필드를 사용하여이를 클라이언트의 논리에 구축 할 수 있음). 스키마를 디자인 할 때 데이터 일관성을 유지하는 방법을 고려하십시오. 일반적으로 문서에 많이 보관할수록 좋습니다.
설명하는 내용에 대해 설명을 포함시키고 각 설명에 ObjectID가있는 id 필드를 제공합니다. ObjectID에는 타임 스탬프가 포함되어 있으므로 원하는 경우 만든 대신 사용할 수 있습니다.
답변
일반적으로 엔터티간에 일대일 또는 일대 다 관계가 있으면 포함이 좋고, 다 대다 관계가 있으면 참조가 좋습니다.
답변
지정된 주석을 편집하려면 내용과 질문을 얻는 방법은 무엇입니까?
하위 문서별로 쿼리 할 수 있습니다 : db.question.find({'comments.content' : 'xxx'})
.
그러면 전체 질문 문서가 반환됩니다. 지정된 주석을 편집하려면 클라이언트에서 주석을 찾아서 편집 한 후 DB에 다시 저장해야합니다.
일반적으로 문서에 객체 배열이 포함되어 있으면 해당 하위 객체를 클라이언트 쪽에서 수정해야합니다.
답변
글쎄, 나는 조금 늦었지만 여전히 내 스키마 생성 방식을 공유하고 싶습니다.
고전 OOP에서와 마찬가지로 단어로 설명 할 수있는 모든 것에 대한 스키마가 있습니다.
EG
- 논평
- 계정
- 사용자
- 블로그 포스트
- …
모든 스키마는 문서 또는 하위 문서로 저장 될 수 있으므로 각 스키마마다이를 선언합니다.
문서:
- 참조로 사용할 수 있습니다. (예 : 사용자가 의견을 작성했습니다.-> 의견은 사용자에 대한 “제작자”참조입니다.)
- 응용 프로그램의 “루트”입니다. (예 : 블로그 포스트-> 블로그 포스트에 관한 페이지가 있습니다)
하위 문서 :
- 한 번만 사용할 수 있으며 참조가 아닙니다. (예 : 댓글은 블로그 포스트에 저장됩니다)
- 응용 프로그램에서 “루트”가 아닙니다. (댓글은 블로그 포스트 페이지에 표시되지만 해당 페이지는 여전히 블로그 포스트에 관한 것입니다)
답변
나는이 질문을 스스로 조사 하면서이 작은 프레젠테이션을 보았습니다. 나는 정보와 정보의 표현이 얼마나 잘 구성되어 있는지 놀랐다.
http://openmymind.net/Multiple-Collections-Versus-Embedded-Documents
요약했습니다 :
일반적으로 [자식 문서]가 많거나 큰 경우에는 별도의 모음이 가장 좋습니다.
더 작거나 적은 문서는 자연스럽게 포함시키는 경향이 있습니다.
답변
나는 이것이 아주 오래되었다는 것을 알고 있지만 지정된 주석 만 반환하는 방법에 대한 OP의 질문에 대한 답을 찾고 있다면 $ (조회) 연산자를 다음과 같이 사용할 수 있습니다 .
db.question.update({'comments.content': 'xxx'}, {'comments.$': true})
답변
예, 우리는 문서의 참조를 사용할 수 있습니다 .SQL i 조인과 같은 다른 문서를 채우려면 mongo db에서는 하나의 많은 관계 문서에 매핑하는 조인이 없습니다. 대신 채우기 를 사용 하여 시나리오를 수행 할 수 있습니다.
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Number,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = Schema({
_creator : { type: Number, ref: 'Person' },
title : String,
fans : [{ type: Number, ref: 'Person' }]
});
인구는 문서의 지정된 경로를 다른 컬렉션의 문서로 자동으로 바꾸는 프로세스입니다. 단일 문서, 여러 문서, 일반 개체, 여러 일반 개체 또는 쿼리에서 반환 된 모든 개체를 채울 수 있습니다. 몇 가지 예를 살펴 보겠습니다.
더 자세한 정보는 http://mongoosejs.com/docs/populate.html을 참조하십시오.