오늘 한 것
1. 미디어 관련 모델링 #2 (MongoDB)
// 미디어 schema
{
mediaId: UUID(),
media: {
mediaPath : "uri or url string",
mediaMetadata: {
mediaType:"dedicate,cloud,publish",
mediaTitle:"media title string",
uploadDate: ObjectId.getTimestamp(),
modifiedDate: "timedate",
exif:{ //EXIF데이터가 들어가면 좋겠다
},
}
}
},
위와 같이 미디어 타입으로 언급된 것은 다음과 같은 고민이 있기 때문이다.
- 미디어와 글을 같은 타입으로 볼 것인가 → 전통적인 CMS와 다르게 모든 글을 가지고 올 때 개별 사진을 같이 가지고 왔으면 좋겠다. 즉, 글이 주가되는 CMS가 아니라 사진이 주를 이루는 CMS.
- 미디어에 캡션을 얼마나 부착할 것인가 → 가령 한장의 사진이나 유투브 영상에 담긴 스토리에 대한 reference
- 결론적으로 미디어도 하나의 글(객체)이면 좋겠다. 아래와 같이 고쳐본다
// 미디어→객체 schema
{
Id: UUID(), //_id를 대신해 눈에 보이는 고유 번호가 필요해 보인다. 가령 DB를 이전했다거나. 변하면 안되는 상품코드라던가.
title:"string",
uploadDate: ObjectId.getTimestamp(),
modifiedDate:,
content: {
path: "uri or url string",
linkedDocument: [reference1, reference2, reference3] // 일종의 컴포넌트 개념
metadata: {
type:"dedicate,cloud,publish",
modifiedDate: "timedate", // OS상의 파일 스탬프를 가지고 올 수 있으면 좋겠다.
exif:{
//EXIF데이터가 들어가면 좋겠다.
},
}
}
},
아래와 같이 linkedDocument로 따로 관리한다. 왠만하면 마크다운을 써야지.
// linkedDocument
{
Id: UUID(),
title: "String" //모든 단락에는 소제목이 필요하다.
uploadDate:,
modifiedDate:,
content: "markdown string"
}
이렇게 되면 겹치는데 이건 내부에서 분기를 해서 구분해야할까? 아니면 따로 타입을 만드는게 맞을까?
2. MongoDB 기본 쿼리
mongo Shell
- MongoDB에서는 mongo쉘에서 작업을 할 수 있다. 아래 기본 쿼리에 대해서 정리해봤다.
- 시작하는 몇가지 방법
mongo
mongo --host 10.10.10.1:28015
mongod --config /usr/local/etc/mongod.conf --fork
1) insert
db.inventory.insertOne(
{ item: "canvas", qty: 100, tags: ["cotton"], size: { h: 28, w: 35.5, uom: "cm" } }
)
db.inventory.insertMany([
{ item: "journal", qty: 25, tags: ["blank", "red"], size: { h: 14, w: 21, uom: "cm" } },
{ item: "mat", qty: 85, tags: ["gray"], size: { h: 27.9, w: 35.5, uom: "cm" } },
{ item: "mousepad", qty: 25, tags: ["gel", "blue"], size: { h: 19, w: 22.85, uom: "cm" } }
])
- 이렇게 삽입하면 document 마다 기본키 역할을 하는 고유한
_id
필드가 생성된다. 값은 기본적으로 ObjectId를 생성한다.
2) update
db.inventory.updateOne(
{ item: "paper" },
{
$set: { "size.uom": "cm", status: "P" },
$currentDate: { lastModified: true }
}
)
db.inventory.updateMany(
{ "qty": { $lt: 50 } },
{
$set: { "size.uom": "in", status: "P" },
$currentDate: { lastModified: true }
}
- $set 연산자를 통해 앞의 paper 아이템을 찾아 변경한다.
- $currentDate 연산자를 통해 lastModified 필드를 변경한다.
3) replace
db.inventory.replaceOne(
{ item: "paper" },
{ item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 40 } ] }
)
- update와 다른점은
_id
필드를 제외한 다른 필드를 전부 지우고 새로 document를 구성한다.
3) delete
db.inventory.deleteMany({})
db.inventory.deleteMany({ status : "A" })
db.inventory.deleteOne( { status: "D" } )
4) find
db.inventory.find( {} )
db.inventory.find( { item: "canvas" } )
습득한 지식
1. EAV패턴과 안티패턴 해법
- 안티패턴이란 ‘실제로 많이 쓰이지만 가독성이나 효율은 떨어지는 코드 또는 구조’를 말한다.
- 기존에 유연한 메타데이터 설계를 위한 key-value구조의 테이블을 따로 관리하는 것이 안티패턴이라고 한다.
- 위 글에 서브타입 모델링 기법을 쓴다는데 이건 좀 더 시간을 갖고 찾아봐야겠다.
- 더 볼만한 글 : ORM은 안티패턴이다
2. 전통적인 엔터티 관계
1) 1:1
2) 1:N
3) N:M
궁금한 점
다음에 진행할 내용
- RDB의 역사
- NoSQL이 등장한 히스토리
- MongoDB; ObjectID
- MongoDB; 기본 연산자
- Hash 함수 (SHA-1, SHA-256, MD5) / 눈사태 효과