SlideShare a Scribd company logo
1 of 14
Download to read offline
MongoDB 활용 가이드
     Chapter 7
  애플리케이션 디자인 팁
> post = {"title" : "My Blog Post",
                                ... "content" : "here's my blog post.",
데모 : 설치                         ... "date" : new Date() }
                                {
                                    "title" : "My Blog Post",
                                    "content" : "here's my blog post.",
$ bin/mongod --dbpath ~/db          "date" : ISODate("2012-01-27T17:17:44.026Z")
=> http://localhost:28017/ 접속   }
                                > db.blog.insert(post)
$ bin/mongo                     > db.blog.find()
> x = 200                       {
200                              "_id" : ObjectId("4f22dc6dc7aca8fc32e67afb"), "title" : "My
>x/5                            Blog Post", "content" : "here's my blog post.", "date" :
40                              ISODate("2012-01-27T17:17:44.026Z") }
> db                            >
test                            > db.blog.findOne()
> use foobar                    {
switched to db foobar               "_id" : ObjectId("4f22dc6dc7aca8fc32e67afb"),
> db                                "title" : "My Blog Post",
foobar                              "content" : "here's my blog post.",
                                    "date" : ISODate("2012-01-27T17:17:44.026Z")
                                }
                                                                                               }
데모 : 설치

> post.comments = [ ]
[]
> db.blog.update({title : "My Blog Post"}, post)
> db.blog.findOne()
{
     "_id" : ObjectId("4f22dc6dc7aca8fc32e67afb"),
     "title" : "My Blog Post",
     "content" : "here's my blog post.",
     "date" : ISODate("2012-01-27T17:17:44.026Z"),
     "comments" : [ ]
}
>
> db.blog.remove({title : "My Blog Post"})
> db.blog.find()
>
Tip 1. 속도가 중요하면 복제를 , 데이터
무결성이 중요하면 참조를 사용하라


여러 문서가 공동으로 사용하는 데이터는
● 내장(embedded)되거나 => 비정규화
● 참조될 수 있다         => 정규화

결정 요인
● 읽기 수행시 비용 발생 여부
● 데이터 변경이 드문가
● 일관성이 얼마나 중요한 요소인가
● 읽기는 빨라야 하는가
Tip 1. 속도가 중요하면 복제를 , 데이터
무결성이 중요하면 참조를 사용하라


● 비정규화
 ○ 데이터 일관성(consistency) 해칠 수 있다.
 ○ 데이터 불일치가 상대적으로 덜 중요하거나
   나중에 보정해도 괜찮을 때 사용
 ○ 한번의 쿼리로 수행. 성능 저하 요인이 없음


● 정규화
 ○ 아주 짧은 기간의 불일치도 허용할 수 없을 때
 ○ 추가적인 쿼리를 수행하기 때문에 성능 저하
 ○ 원자성 유지한 채 수정 가능
데모 : 정규화                                   > product1._id
                                               ObjectId("4f22f609c7aca8fc32e67afd")
                                               > product2._id
> product1 = { "name" : "A", "price" : 100 }
                                               ObjectId("4f22f60bc7aca8fc32e67afe")
{ "name" : "A", "price" : 100 }
                                               > product3._id
> product2 = { "name" : "B", "price" : 200 }
                                               ObjectId("4f22f60ec7aca8fc32e67aff")
{ "name" : "B", "price" : 200 }
                                               > order1 = {
> product3 = { "name" : "C", "price" : 300 }
                                               ... "user" : "User01",
{ "name" : "C", "price" : 300 }
                                               ... "items" : [
>
                                               ...       product1._id,
> db.amazon.product.insert(product1)
                                               ...       product2._id,
> db.amazon.product.insert(product2)
                                               ...       product3._id
> db.amazon.product.insert(product3)
                                               ...     ]
> db.amazon.product.find()
                                               ... }
{ "_id" : ObjectId
                                               {
("4f22f609c7aca8fc32e67afd"), "name" :
                                                      "user" : "User01",
"A", "price" : 100 }
                                                      "items" : [
{ "_id" : ObjectId
                                                            ObjectId("4f22f609c7aca8fc32e67afd"),
("4f22f60bc7aca8fc32e67afe"), "name" :
                                                            ObjectId("4f22f60bc7aca8fc32e67afe"),
"B", "price" : 200 }
                                                            ObjectId("4f22f60ec7aca8fc32e67aff")
{ "_id" : ObjectId
                                                      ]
("4f22f60ec7aca8fc32e67aff"), "name" :
                                               }
"C", "price" : 300 }
> order2 = {
                                                      ... "user" : "User02",
                                                      ... "items" : [ p1, p2, p3 ]

    데모 : 비정규화                                         ... }
                                                      {
                                                              "user" : "User02",
                                                              "items" : [
> p1 = db.amazon.product.findOne( {"name" : "A"} );                   {
{                                                                           "_id" : ObjectId
     "_id" : ObjectId("4f22f609c7aca8fc32e67afd"),    ("4f22f609c7aca8fc32e67afd"),
     "name" : "A",                                                          "name" : "A",
     "price" : 102                                                          "price" : 102
                                                                      },
}
                                                                      {
> p2 = db.amazon.product.findOne( {"name" : "B"} );                         "_id" : ObjectId
{                                                     ("4f22f60bc7aca8fc32e67afe"),
     "_id" : ObjectId("4f22f60bc7aca8fc32e67afe"),                          "name" : "B",
     "name" : "B",                                                          "price" : 200
     "price" : 200                                                    },
                                                                      {
}
                                                                            "_id" : ObjectId
> p3 = db.amazon.product.findOne( {"name" : "C"} );   ("4f22f60ec7aca8fc32e67aff"),
{                                                                           "name" : "C",
     "_id" : ObjectId("4f22f60ec7aca8fc32e67aff"),                          "price" : 300
     "name" : "C",                                                    }
     "price" : 300                                            ]
}                                                     }
                                                      > db.amazon.order.insert(order2);
Tip 2. 데이터가 미래에도 유용한 상태
이기를 원하면 정규화하라


● 데이터는 지속적으로 발달한다.
● 오래된 데이터는 갱신되거나 잊혀진다.
● 새로운 쿼리에 맞는 데이터베이스 최적화

나중에 다른 애플리케이션에서 다른 방식으로
데이터에 대한 쿼리를 수행하도록 하려면 데이
터를 정규화해야 한다.
Tip 3. 단일 쿼리로 데이터를 가져오라


MongoDB 스키마는 하나의 쿼리가 하나의 애플
리케이션 단위를 수행하도록 설계해야 한다

● 사례 1 : 블로그
  ○ posts 컬렉션에 저장된 최근 10개의 포스트
  ○ 해당 태그가 달린 최근 20개 포스트
  > db.posts.find( {}, {"title" : 1, "author" : 1, "slug" : 1, "_id" : 0} ).sort(
  ... {"date" : -1}).limit(10)
  > db.posts.find( {"tag" : someTag}, {"title" : 1, "author" : 1,
  ... "slug" : 1, "_id" : 0} ).sort( {"data" : -1} ).limit(20)
  > db.authors.findOne( {"name" : authorName} )
Tip 3. 단일 쿼리로 데이터를 가져오라


● 사례 2 : 사진 게시판
  ○ 애플리케이션 단위 : 스레드 하나의 메시지 중 스무
    개를 표시하는 것
  > db.posts.find( {"threadId" : id} ).sort( {"date" : 1} ).limit(20)
  > db.posts.find( {"threadId" : id, "date" : {"$gt" : latestDateSeen}} ).
  ... sort( {"date" : 1} ).limit(20)



● 하지만 현실은 만만치 않다!

Q : latestDateSeen
Tip 4. 의존적인 필드는 내장하라


● 어떤 문서를 내장할지 참조할지 고려할 때는
  그 필드에 저장된 정보 자체가 필요한지 아
  니면 그 필드가 속한 문서의 구조가 필요한
  지를 자문해보자. (ex. 태그, 댓글)

● 어떤 데이터를 사용하는 문서가 단 하나뿐이
  라면 그 정보는 그 문서에 내장한다.

Q : 조인 테이블?
Tip 5. 특정 시점의 데이터는 내장하라


어떤 데이터의 특정 시점의 스냅샷을 원하는 경
우에는 데이터 내장 방식을 사용한다.

ex> orders 문서의 주소를 나타내는 필드
고객이 주소를 수정했다고 해서 이전 주문내역
의 배송지 주소까지 바뀌는 것을 원하지 않는
다.
Tip 6. 계속해서 커지는 필드는 내장하
지 말라


MongoDB가 데이터를 저장하는 방식 때문에...
● 많은 양의 서브문서를 내장하는 것은 상관없
  으나
● 배열의 끝에 계속해서 데이터를 추가하는 것
  은 상당히 비효율적이다.

=> 댓글같이 애플리케이션마다 다양한 양상을
보이는 극단적 케이스에서는 별개의 문서에 저
장하는 것을 고려하자
감사합니다.

More Related Content

What's hot

[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)
Sang Don Kim
 
Mongo db로 배우는 nosql
Mongo db로 배우는 nosqlMongo db로 배우는 nosql
Mongo db로 배우는 nosql
Suwon Chae
 

What's hot (20)

JSON with C++ & C#
JSON with C++ & C#JSON with C++ & C#
JSON with C++ & C#
 
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)
[Td 2015]틱틱대도 써야 하는 windows 10 앱 개발, c# tips & tricks(송기수)
 
Ch1 일래스틱서치 클러스터 시작
Ch1 일래스틱서치 클러스터 시작Ch1 일래스틱서치 클러스터 시작
Ch1 일래스틱서치 클러스터 시작
 
Node.js + Express + MongoDB
Node.js + Express + MongoDBNode.js + Express + MongoDB
Node.js + Express + MongoDB
 
파이썬 언어 기초
파이썬 언어 기초파이썬 언어 기초
파이썬 언어 기초
 
201804 neo4 j_cypher_guide
201804 neo4 j_cypher_guide201804 neo4 j_cypher_guide
201804 neo4 j_cypher_guide
 
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
일래스틱 서치 ch7. 일래스틱 서치 클러스터 세부사항
 
Logstash, ElasticSearch, Kibana
Logstash, ElasticSearch, KibanaLogstash, ElasticSearch, Kibana
Logstash, ElasticSearch, Kibana
 
elasticsearch_적용 및 활용_정리
elasticsearch_적용 및 활용_정리elasticsearch_적용 및 활용_정리
elasticsearch_적용 및 활용_정리
 
Python 웹 프로그래밍
Python 웹 프로그래밍Python 웹 프로그래밍
Python 웹 프로그래밍
 
[week14] Getting started with D3.js
[week14] Getting started with D3.js[week14] Getting started with D3.js
[week14] Getting started with D3.js
 
Elastic Search (엘라스틱서치) 입문
Elastic Search (엘라스틱서치) 입문Elastic Search (엘라스틱서치) 입문
Elastic Search (엘라스틱서치) 입문
 
제2회 한글형태소분석기 기술 세니마 발표(solr 활용 입문) by 김지훈
제2회 한글형태소분석기 기술 세니마 발표(solr 활용 입문) by 김지훈제2회 한글형태소분석기 기술 세니마 발표(solr 활용 입문) by 김지훈
제2회 한글형태소분석기 기술 세니마 발표(solr 활용 입문) by 김지훈
 
Hacosa j query 4th
Hacosa j query 4thHacosa j query 4th
Hacosa j query 4th
 
5-1. html5 graphics
5-1. html5 graphics5-1. html5 graphics
5-1. html5 graphics
 
Mongo db로 배우는 nosql
Mongo db로 배우는 nosqlMongo db로 배우는 nosql
Mongo db로 배우는 nosql
 
elasticsearch
elasticsearchelasticsearch
elasticsearch
 
개발자가 알면 좋은 Mongodb
개발자가 알면 좋은 Mongodb개발자가 알면 좋은 Mongodb
개발자가 알면 좋은 Mongodb
 
Fundamental of ELK Stack
Fundamental of ELK StackFundamental of ELK Stack
Fundamental of ELK Stack
 
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
집단 지성 (Programming collective intelligence) 스터디: Chapter 4 - Searching & Ranking
 

Viewers also liked

турнир вежливых ребят
турнир вежливых ребяттурнир вежливых ребят
турнир вежливых ребят
Ольга Бобок
 
WaterHackathonTelAviv - instructions
WaterHackathonTelAviv - instructionsWaterHackathonTelAviv - instructions
WaterHackathonTelAviv - instructions
StarTau-WH
 

Viewers also liked (20)

Física y ciencia
Física y cienciaFísica y ciencia
Física y ciencia
 
Shira
ShiraShira
Shira
 
Tabitha 2012 power point
Tabitha 2012 power pointTabitha 2012 power point
Tabitha 2012 power point
 
Cорокин Захар Артёмович
Cорокин Захар АртёмовичCорокин Захар Артёмович
Cорокин Захар Артёмович
 
Google AdWords 101
Google AdWords 101Google AdWords 101
Google AdWords 101
 
Larisa
LarisaLarisa
Larisa
 
Мой дедушка герой
Мой дедушка геройМой дедушка герой
Мой дедушка герой
 
турнир вежливых ребят
турнир вежливых ребяттурнир вежливых ребят
турнир вежливых ребят
 
ADHD In The Workplace
ADHD In The WorkplaceADHD In The Workplace
ADHD In The Workplace
 
Indira's New York Food tour
Indira's New York Food tourIndira's New York Food tour
Indira's New York Food tour
 
конёк горбунок
конёк горбунокконёк горбунок
конёк горбунок
 
Azul
AzulAzul
Azul
 
El aquí y el ahora
El aquí y el ahoraEl aquí y el ahora
El aquí y el ahora
 
Портрет бабушки
Портрет бабушкиПортрет бабушки
Портрет бабушки
 
Встреча с поэтом Е.Н. Ткач
Встреча с поэтом Е.Н. ТкачВстреча с поэтом Е.Н. Ткач
Встреча с поэтом Е.Н. Ткач
 
Обо мне
Обо мнеОбо мне
Обо мне
 
WaterHackathonTelAviv - instructions
WaterHackathonTelAviv - instructionsWaterHackathonTelAviv - instructions
WaterHackathonTelAviv - instructions
 
Laporan
LaporanLaporan
Laporan
 
Памятник природы "Троицкая степь".
Памятник природы "Троицкая степь".Памятник природы "Троицкая степь".
Памятник природы "Троицкая степь".
 
Critical studies wk1
Critical studies wk1Critical studies wk1
Critical studies wk1
 

Similar to Mongo db 활용 가이드 ch7

Mongo db 시작하기
Mongo db 시작하기Mongo db 시작하기
Mongo db 시작하기
OnGameServer
 
Naver api for android
Naver api for androidNaver api for android
Naver api for android
Sangon Lee
 
Web Components 101 polymer & brick
Web Components 101 polymer & brickWeb Components 101 polymer & brick
Web Components 101 polymer & brick
yongwoo Jeon
 

Similar to Mongo db 활용 가이드 ch7 (20)

Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3Daejeon IT Developer Conference Hibernate3
Daejeon IT Developer Conference Hibernate3
 
First Step In Ajax Korean
First Step In Ajax KoreanFirst Step In Ajax Korean
First Step In Ajax Korean
 
3-2. selector api
3-2. selector api3-2. selector api
3-2. selector api
 
5-4. html5 offline and storage
5-4. html5 offline and storage5-4. html5 offline and storage
5-4. html5 offline and storage
 
[XECon+PHPFest 2014] jQuery 개발자에서 AngularJS 개발자 되기
[XECon+PHPFest 2014] jQuery 개발자에서 AngularJS 개발자 되기[XECon+PHPFest 2014] jQuery 개발자에서 AngularJS 개발자 되기
[XECon+PHPFest 2014] jQuery 개발자에서 AngularJS 개발자 되기
 
//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작
//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작
//BUILD/ Seoul - .NET의 현재와 미래. 그 새로운 시작
 
Mongo db 시작하기
Mongo db 시작하기Mongo db 시작하기
Mongo db 시작하기
 
Mongo db 최범균
Mongo db 최범균Mongo db 최범균
Mongo db 최범균
 
Coded ui가이드
Coded ui가이드Coded ui가이드
Coded ui가이드
 
Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기Django를 Django답게, Django로 뉴스 사이트 만들기
Django를 Django답게, Django로 뉴스 사이트 만들기
 
Hacosa jquery 1th
Hacosa jquery 1thHacosa jquery 1th
Hacosa jquery 1th
 
Dependency Injection 소개
Dependency Injection 소개Dependency Injection 소개
Dependency Injection 소개
 
Python codelab2
Python codelab2Python codelab2
Python codelab2
 
알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations알아봅시다, Polymer: Web Components & Web Animations
알아봅시다, Polymer: Web Components & Web Animations
 
Naver api for android
Naver api for androidNaver api for android
Naver api for android
 
Web Components 101 polymer & brick
Web Components 101 polymer & brickWeb Components 101 polymer & brick
Web Components 101 polymer & brick
 
Class10
Class10Class10
Class10
 
처음배우는 자바스크립트, 제이쿼리 #4
처음배우는 자바스크립트, 제이쿼리 #4처음배우는 자바스크립트, 제이쿼리 #4
처음배우는 자바스크립트, 제이쿼리 #4
 
Hibernate 기초
Hibernate 기초Hibernate 기초
Hibernate 기초
 
웹개발자가 알아야할 기술
웹개발자가 알아야할 기술웹개발자가 알아야할 기술
웹개발자가 알아야할 기술
 

More from 주영 송

5일차.map reduce 활용
5일차.map reduce 활용5일차.map reduce 활용
5일차.map reduce 활용
주영 송
 
Regression & Classification
Regression & ClassificationRegression & Classification
Regression & Classification
주영 송
 
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
주영 송
 
SNA & R (20121011)
SNA & R (20121011)SNA & R (20121011)
SNA & R (20121011)
주영 송
 
Recommendation system 소개 (1)
Recommendation system 소개 (1)Recommendation system 소개 (1)
Recommendation system 소개 (1)
주영 송
 
Cloud burst tutorial
Cloud burst tutorialCloud burst tutorial
Cloud burst tutorial
주영 송
 
Cloud burst 소개
Cloud burst 소개Cloud burst 소개
Cloud burst 소개
주영 송
 

More from 주영 송 (12)

R_datamining
R_dataminingR_datamining
R_datamining
 
Giraph
GiraphGiraph
Giraph
 
Mahout
MahoutMahout
Mahout
 
5일차.map reduce 활용
5일차.map reduce 활용5일차.map reduce 활용
5일차.map reduce 활용
 
Regression & Classification
Regression & ClassificationRegression & Classification
Regression & Classification
 
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
MapReduce 실행 샘플 (K-mer Counting, K-means Clustering)
 
SNA & R (20121011)
SNA & R (20121011)SNA & R (20121011)
SNA & R (20121011)
 
Recommendation system 소개 (1)
Recommendation system 소개 (1)Recommendation system 소개 (1)
Recommendation system 소개 (1)
 
Cloud burst tutorial
Cloud burst tutorialCloud burst tutorial
Cloud burst tutorial
 
Cloud burst 소개
Cloud burst 소개Cloud burst 소개
Cloud burst 소개
 
Cuda intro
Cuda introCuda intro
Cuda intro
 
R intro
R introR intro
R intro
 

Mongo db 활용 가이드 ch7

  • 1. MongoDB 활용 가이드 Chapter 7 애플리케이션 디자인 팁
  • 2. > post = {"title" : "My Blog Post", ... "content" : "here's my blog post.", 데모 : 설치 ... "date" : new Date() } { "title" : "My Blog Post", "content" : "here's my blog post.", $ bin/mongod --dbpath ~/db "date" : ISODate("2012-01-27T17:17:44.026Z") => http://localhost:28017/ 접속 } > db.blog.insert(post) $ bin/mongo > db.blog.find() > x = 200 { 200 "_id" : ObjectId("4f22dc6dc7aca8fc32e67afb"), "title" : "My >x/5 Blog Post", "content" : "here's my blog post.", "date" : 40 ISODate("2012-01-27T17:17:44.026Z") } > db > test > db.blog.findOne() > use foobar { switched to db foobar "_id" : ObjectId("4f22dc6dc7aca8fc32e67afb"), > db "title" : "My Blog Post", foobar "content" : "here's my blog post.", "date" : ISODate("2012-01-27T17:17:44.026Z") } }
  • 3. 데모 : 설치 > post.comments = [ ] [] > db.blog.update({title : "My Blog Post"}, post) > db.blog.findOne() { "_id" : ObjectId("4f22dc6dc7aca8fc32e67afb"), "title" : "My Blog Post", "content" : "here's my blog post.", "date" : ISODate("2012-01-27T17:17:44.026Z"), "comments" : [ ] } > > db.blog.remove({title : "My Blog Post"}) > db.blog.find() >
  • 4. Tip 1. 속도가 중요하면 복제를 , 데이터 무결성이 중요하면 참조를 사용하라 여러 문서가 공동으로 사용하는 데이터는 ● 내장(embedded)되거나 => 비정규화 ● 참조될 수 있다 => 정규화 결정 요인 ● 읽기 수행시 비용 발생 여부 ● 데이터 변경이 드문가 ● 일관성이 얼마나 중요한 요소인가 ● 읽기는 빨라야 하는가
  • 5. Tip 1. 속도가 중요하면 복제를 , 데이터 무결성이 중요하면 참조를 사용하라 ● 비정규화 ○ 데이터 일관성(consistency) 해칠 수 있다. ○ 데이터 불일치가 상대적으로 덜 중요하거나 나중에 보정해도 괜찮을 때 사용 ○ 한번의 쿼리로 수행. 성능 저하 요인이 없음 ● 정규화 ○ 아주 짧은 기간의 불일치도 허용할 수 없을 때 ○ 추가적인 쿼리를 수행하기 때문에 성능 저하 ○ 원자성 유지한 채 수정 가능
  • 6. 데모 : 정규화 > product1._id ObjectId("4f22f609c7aca8fc32e67afd") > product2._id > product1 = { "name" : "A", "price" : 100 } ObjectId("4f22f60bc7aca8fc32e67afe") { "name" : "A", "price" : 100 } > product3._id > product2 = { "name" : "B", "price" : 200 } ObjectId("4f22f60ec7aca8fc32e67aff") { "name" : "B", "price" : 200 } > order1 = { > product3 = { "name" : "C", "price" : 300 } ... "user" : "User01", { "name" : "C", "price" : 300 } ... "items" : [ > ... product1._id, > db.amazon.product.insert(product1) ... product2._id, > db.amazon.product.insert(product2) ... product3._id > db.amazon.product.insert(product3) ... ] > db.amazon.product.find() ... } { "_id" : ObjectId { ("4f22f609c7aca8fc32e67afd"), "name" : "user" : "User01", "A", "price" : 100 } "items" : [ { "_id" : ObjectId ObjectId("4f22f609c7aca8fc32e67afd"), ("4f22f60bc7aca8fc32e67afe"), "name" : ObjectId("4f22f60bc7aca8fc32e67afe"), "B", "price" : 200 } ObjectId("4f22f60ec7aca8fc32e67aff") { "_id" : ObjectId ] ("4f22f60ec7aca8fc32e67aff"), "name" : } "C", "price" : 300 }
  • 7. > order2 = { ... "user" : "User02", ... "items" : [ p1, p2, p3 ] 데모 : 비정규화 ... } { "user" : "User02", "items" : [ > p1 = db.amazon.product.findOne( {"name" : "A"} ); { { "_id" : ObjectId "_id" : ObjectId("4f22f609c7aca8fc32e67afd"), ("4f22f609c7aca8fc32e67afd"), "name" : "A", "name" : "A", "price" : 102 "price" : 102 }, } { > p2 = db.amazon.product.findOne( {"name" : "B"} ); "_id" : ObjectId { ("4f22f60bc7aca8fc32e67afe"), "_id" : ObjectId("4f22f60bc7aca8fc32e67afe"), "name" : "B", "name" : "B", "price" : 200 "price" : 200 }, { } "_id" : ObjectId > p3 = db.amazon.product.findOne( {"name" : "C"} ); ("4f22f60ec7aca8fc32e67aff"), { "name" : "C", "_id" : ObjectId("4f22f60ec7aca8fc32e67aff"), "price" : 300 "name" : "C", } "price" : 300 ] } } > db.amazon.order.insert(order2);
  • 8. Tip 2. 데이터가 미래에도 유용한 상태 이기를 원하면 정규화하라 ● 데이터는 지속적으로 발달한다. ● 오래된 데이터는 갱신되거나 잊혀진다. ● 새로운 쿼리에 맞는 데이터베이스 최적화 나중에 다른 애플리케이션에서 다른 방식으로 데이터에 대한 쿼리를 수행하도록 하려면 데이 터를 정규화해야 한다.
  • 9. Tip 3. 단일 쿼리로 데이터를 가져오라 MongoDB 스키마는 하나의 쿼리가 하나의 애플 리케이션 단위를 수행하도록 설계해야 한다 ● 사례 1 : 블로그 ○ posts 컬렉션에 저장된 최근 10개의 포스트 ○ 해당 태그가 달린 최근 20개 포스트 > db.posts.find( {}, {"title" : 1, "author" : 1, "slug" : 1, "_id" : 0} ).sort( ... {"date" : -1}).limit(10) > db.posts.find( {"tag" : someTag}, {"title" : 1, "author" : 1, ... "slug" : 1, "_id" : 0} ).sort( {"data" : -1} ).limit(20) > db.authors.findOne( {"name" : authorName} )
  • 10. Tip 3. 단일 쿼리로 데이터를 가져오라 ● 사례 2 : 사진 게시판 ○ 애플리케이션 단위 : 스레드 하나의 메시지 중 스무 개를 표시하는 것 > db.posts.find( {"threadId" : id} ).sort( {"date" : 1} ).limit(20) > db.posts.find( {"threadId" : id, "date" : {"$gt" : latestDateSeen}} ). ... sort( {"date" : 1} ).limit(20) ● 하지만 현실은 만만치 않다! Q : latestDateSeen
  • 11. Tip 4. 의존적인 필드는 내장하라 ● 어떤 문서를 내장할지 참조할지 고려할 때는 그 필드에 저장된 정보 자체가 필요한지 아 니면 그 필드가 속한 문서의 구조가 필요한 지를 자문해보자. (ex. 태그, 댓글) ● 어떤 데이터를 사용하는 문서가 단 하나뿐이 라면 그 정보는 그 문서에 내장한다. Q : 조인 테이블?
  • 12. Tip 5. 특정 시점의 데이터는 내장하라 어떤 데이터의 특정 시점의 스냅샷을 원하는 경 우에는 데이터 내장 방식을 사용한다. ex> orders 문서의 주소를 나타내는 필드 고객이 주소를 수정했다고 해서 이전 주문내역 의 배송지 주소까지 바뀌는 것을 원하지 않는 다.
  • 13. Tip 6. 계속해서 커지는 필드는 내장하 지 말라 MongoDB가 데이터를 저장하는 방식 때문에... ● 많은 양의 서브문서를 내장하는 것은 상관없 으나 ● 배열의 끝에 계속해서 데이터를 추가하는 것 은 상당히 비효율적이다. => 댓글같이 애플리케이션마다 다양한 양상을 보이는 극단적 케이스에서는 별개의 문서에 저 장하는 것을 고려하자