프로젝트 DB를 MongoDB로 결정하여, 데이터 모델링에 대해 학습합니다.
( 작성자 역시 입문자로써 문서를 참고하여 해석한대로 작성하였습니다 )
NoSQL
SQL 계열 쿼리 언어를 사용할 수 있다는 사실을 강조하며 "Not-Only SQL" 또는,
전통적인 관계형 DB(RDB) 보다 덜 제한적이라는 "Non-Relational Operational SQL" 로 불리는데,
보통, "Not-Only SQL"로 불립니다.
Document
RDB의 행보다 유연한 모델인 Document를 지향합니다.
RDB와 다르게 고정된 스키마가 아닌, 동적 스키마입니다.
따라서, 하나의 컬렉션 안의 Document들은 다른 스키마를 가질 수 있습니다.
MongoDB는 통신 규격으로 JSON을 사용합니다. 한개 이상의 Key-Value 쌍으로 이루어집니다.
//user
{
_id : "hanganda23",
name : "yuno",
}
관계 데이터를 저장하는 유형 2가지
두 종류의 Document의 관계에서, 하나의 Document 데이터를 다른 Documnet에 포함시키는 방법입니다.
//User
{
_id : "hanganda",
name : "yuno",
address : {
street : "Banpo dae-ro",
city : "Seoul",
zip : "111111",
},
}
user.address에 Address Documnet가 통째로 저장됩니다.
Document를 통째로 저장하는 것이 아닌, 참조할 수 있도록 id를 저장합니다.
(관계형 DB와 유사)
//movie
{
"_id" : 1 ,
"title" : "The Arrival of a Train" ,
"year" : 1896 ,
}
//movie_detail
{
"_id" : 156 ,
"movie_id" : 1 , // movie Colletion 참조 (*)
" plot " : "한 무리의 사람들이 기차역에서... " ,
"fullplot" : "한 무리의 사람들이 기차역에서 플랫폼을 따라 다가오는 기차를 기다리고 있습니다."
"type": "movie",
"directors": [ "Auguste Lumière", "Louis Lumière" ],
"imdb": {
"rating": 7.3,
"votes": 5043,
"id": 12
},
"countries": [ "France" ],
"genres": [ "Documentary", "Short" ],
}
(*) : movie_id
항목이 movie 컬렉션을 참조하고 있습니다.
각 관계와 상황에 따라 어떤 저장 방식이 유리한지 판단하고, 어떻게 하는지 학습합니다.
유저와 주소를 1:1 매핑하는 예시에서, embedded가 reference보다 이점이 있습니다.
주소 정보가 자주 요청될 때,
embedded은 한번의 요청으로 유저의 정보 전체를 검색할 수 있습니다.
하지만, reference은 추가적인 요청을 통해야만 가져올 수 있습니다.
하지만, Embedded pattern 은
불필요한 필드를 포함한 큰 문서가 될 수 있다는 잠재적인 문제를 가지고 있습니다.
이러한 불필요한 데이터는 성능 저하를 일으킵니다.
위 쪽의 예시 Movie, MovieDetail이 하나의 컬렉션으로 표현 되었다고 생각해봅시다.
간단한 개요를 표시할 때는, 필요하지 않는 몇몇 필드를 포함하고 있습니다.
이럴 때는, 두 개의 컬렉션으로 분할하고, 참조합니다.
자주 로드하는 정보를 Movie 컬렉션에,
영화의 세부 데이터와 같은 적게 검색 되는 데이터 정보를 Movie_detail 컬렉션에 분할하고 참조합니다.
자주 액세스하는 데이터만 포함시킨 작은 문서를 사용하여, 데이터의 읽기 성능을 향상시킵니다.
user의 address가 2개 이상이며, address 정보가 user와 함께 자주 검색되는 경우
Embedded는 마찬가지로 하나의 쿼리로 검색할 수 있습니다.
{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}
역시, 필드가 제한되지 않는 경우 너무 큰 Document로 이어질 수 있습니다.
쇼핑몰을 예로,
제품에 대한 리뷰가 제한 없이 작성되어, 하나의 제품 Document가 너무 커지게 됩니다.
이럴 때는, 프로그램에 필요한 데이터만 포함할 수 있습니다.
사용자가 제품 페이지에 방문하면 어플리케이션은 10개의 가장 최근 리뷰를 로드한다고 합니다.
자주 사용되는 10개의 최근 리뷰와, 전체 리뷰 두 개의 컬렉션으로 분할합니다.
//product
{
"_id": 1,
"name": "Super Widget",
"description": "This is the most useful item in your toolbox.",
"price": { "value": NumberDecimal("119.99"), "currency": "USD" },
"reviews": [
{
"review_id": 786,
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
}
//최근 10개만 포함
]
}
//review
//리뷰 전체
{
"review_id": 786,
"product_id": 1, // product._id
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
}
{
"review_id": 785,
"product_id": 1, // product._id
"review_author": "Trina",
"review_text": "Nice product. Slow shipping.",
"published_date": ISODate("2019-02-17")
}
자주 사용되는 데이터를 하나의 쿼리로 검색하면서, Document가 제한 없이 커지는 것을 방지합니다.
추가로, 책과 작성자의 관계를 모델링 할 때,
Embeddeding 했다면 책에 작성자 정보가 반복되게 됩니다.
//book
{
title : "MongoDB : The Definitive Guide" ,
저자 : [ "Kristina Chodorow" , "Mike Dirolf" ],
published_date : ISODate ( "2010-09-24" ),
페이지 : 216 ,
언어 : "English" ,
게시자 : {
이름 : "O'Reilly Media" ,
설립 : 1980 ,
위치 : "CA"
}
}
{
title : "MongoDB 개발자를위한 50 가지 팁과 요령" ,
저자 : "Kristina Chodorow" ,
published_date : ISODate ( "2011-05-06" ),
페이지 : 68 ,
언어 : "English" ,
게시자 : {
이름 : "O'Reilly Media" ,
설립 : 1980 ,
위치 : "CA"
}
}
이러한 반복 문제를 가질 때, 작성자를 책 컬렉션과 별도의 컬렉션에 저장합니다.
다만, 참조할 때 관계가 증가함에 따라 참조를 저장할 위치가 달라집니다.
작성자 한 명당, 도서 수가 제한적이라면
작성자 Document에 도서 참조를 저장하는 것이 유용할 수 있습니다.
{
name: "O'Reilly Media",
founded: 1980,
location: "CA",
books: [123456789, 234567890, ...] // (*)
}
하지만, 배열이 가변적이고 증가합니다.
이를 방지하려면 book 컬렉션에 작성자 참조를 저장합니다.
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "oreilly" // (*)
}
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English",
publisher_id: "oreilly" // (*)
}
책 한권당, 작성자가 여러 명이 될 수 있습니다.
그 작성자 역시 여러 책을 작성했을 수 있습니다.
이 역시, 참조하는 관계의 증가에 따라 참조를 저장할 위치를 지정합니다.
책 한권당, 작성자의 수가 비교적 제한적이므로, 책에서 작성자를 참조합니다.
https://docs.mongodb.com/manual/applications/data-models-relationships/