몽고 디비 MongoDB The Definitive Guide.. Ch. 3

Ch. 3  Creating, Updating, and Deleting Documents

Add, Remove, Update, level of safety vs. speed

Inserting and Saving Documents

Batch Insert

Single TCP request.  한꺼번에 보내면 헤더 중복이 안됨. 배치..
배치는 어플에서 사용하도록 의도. 많은 센서 데이터. 단, 하나의 컬렉션에 여러 다큐를 넣을 때에만 가능.
로 데이터 처리는 mongoimport 를 사용.
16 MB 한계.

Inserts : Internals and Implications

Insert :: BSON 으로 변환. 디비는 이 형식을 이해하고 _아이디 체크. 4 MB 를 넘지 않으면 데이터 validation 을 수행 안하고 바로 그대로 저장.
부작용 : 불량한 데이터 삽입 가능. injection attack 에 안전 ??
모든 메이저 언어의 드라이버는 유효성 검사를 수행.
확실하지 않은 드라이버를 돌릴 때는 디비 서버를 –objcheck 옵션으로 시작할 수 있음.

4메가 이상은 저장 불능. 임의의 한계. 불량 스키마 예방, 퍼포먼스를 위한 것임. 사이즈를 보려면 Object.bsonsize(doc) 을 쉘에서 입력.
전쟁과 평화가 3.14 메가임.

디비는 삽입 시 별로 하는 일이 없으므로 인젝션 어택에 약하지 않음.  고전적인 인젝션 어택은 몽고디비에서는 불가능. 대안 적인 어택.

Removing Documents

db.users.remove()  >> user 컬렉션 전체 삭제. 컬렉션은 살림. 인덱스 삭제. 쿼리를 통해 조건 부여 삭제.

db.mailing.list.remove( { “opt” : true } )  # mailing.list 컬렉션의 opt 값이 참 인 ㅅ람 모두 삭제.

삭제는 undo 없음.

Remove Speed

1만개 삭제 : 맥북에어에서 46초..  드랍을 하면 0.01 초..
전체 컬렉션과 인덱스 삭제..

Updating Documents

2 parameters : query document, modifier document

Document Replacement

Atomic.  Last update will “win” ..  “survive ” ..
같은 조건의 데이터가 여러개 일 때 주의..   update 가 분명한 다큐를 가리켜야함.  “_id” 처럼..

Using Modifiers

데이터 일부만 변경 시..  altering, adding, removing keys, manipulating arrays, embedded documents, _id 는 변경불가.

db.analytics.update({“url” : “www.example.com”},
… {“$inc” : {“pageviews” : 1}})   # 페이지 뷰 늘리기.

[1] Getting started with the “$set” modifier

키에 상응하는 밸류 세팅. 키가 없으면 생성.  밸류의 타입도 변경 (스트링 -> 어레이)
임베디드 다큐의 속성 변경 가능. { “$set” : { “author.name” : “some name” } }  …
$unset :: remove the key.

[2] Incrementing

$inc modifier. :: 현재의 키 증가시킴, 없으면 키 생성. 변경 가능 숫자일 때 유용.  analytics, votes ..  게임 점수 증가.  int, long, double 에 가능.

[3] Array modifiers

$push : 추가..  동일한 내용을 추가하지 않으려면 $ne 쿼리를 병행행
$addToSet : 역시 동일한 내용은 추가 안함.  $each 와 함께 여러개 삽입 가능. ($ne / $push 사용 불가)
<어레이 요소 삭제 방법>
[1] $pop :: 큐 / 스택 처럼 사용하고 싶으면 $pop 사용. { $pop : { key : 1 } } 는 어레이의 끝 요소 삭제. { key : -1} 은 처음 멤버 삭제.
[2] $pull ::  조건으로 검색. 삭제.  매칭되는 여러개 모두 삭제.

[4] Positional array modifier

어레이의 여러 값 변경 방법.  포지션 또는 포지션 연산자 $ 사용.
{ “$inc” : { “comments.0.votes” : 1 } }   # 포지션 지정.. 0번째.  하지만, 많은 경우 위치를 모름. 이때 $ 사용.

db.blog.update( {“comments.author” : “John” },
… { “$set” : { “comments.$.author” : “Jim” } })  # 여러 커멘트에서 작성자 이름을 변경.  (첫번째 것만)
## 첫번째 매치 만 업데이트 함…

[5] Modifier speed

각 명령어마다 성능차이 존재. $inc 는 키에 해당하는 값만 변경하므로 매우 빠름. 대신 어레이 변경자는 다큐의 크기를 변경하므로 느려짐.
($set 역시 비슷함.)
몽고는 사이즈 변경에 따른 완충장치를 두었지만, 원래보다 훨씬 크게 고치면 새로 지정함. 어레이 크기 조정, 어레이 수정 등은 속도 저하.
예제 파이썬 프로그램.   10배 차이..
$push 가 버틀넥인 경우 임베디드 어레이를 별도의 컬렉션에 두는 것도 한 방법.

Upserts [p36]

문서를 찾아서 업데이트하거나, 없으면 생성. 쿼리와 인서트 를 하는 일반적인 경우는 ‘레이스’ 조건 직면.

The ‘save’ Shell Helper

업서트와 비슷. 다큐 인자를 하나 받음. _id 키가 있으면 업서트 실행, 없으면 인서트 실행.
쉘에서 신속하게 수정할 수 있는 방법.

Updateing Multiple Documents [p38]

Update 는 첫번째 요소만 수정. 4번째 인자에 true 를 세팅함으로 모든 멤버 수정 가능. (나중에 바뀔 소지가 있음..  그러므로, 항상 값을 넣을 것. 참/거짓)
멀티 업데이트는 스키마 변경시에 당연히 유리.  생일 선물 주기 기능 ..
몇개가 수정되었나 ? getLastError database command.  ==>  “n” : 5

Returning Updated  Documents [p39]

< getLastError > 로 부터는 제한된 정보밖에 없다. 그래서 findAndModify 가 필요.
일반적인 업데이트와는 약간 다르게 불리고, 느림. 디비 응답을 기다려야 하기 때문.
큐를 조작하고 겟-셑 등의 미세 조작을 수행할 때 편하다.

예> READY, RUNNING DONE 의 세 상태를 갖고 있으면.
“레디”를 가져와서
이놈을 “러닝” 으로 바꾸고.. 액션을 시작한 후 끝나면
“던” 으로 바꾸는 과정을 해야 함.
이 과정은 “레이스 조건”. 대안은 복잡.
타이밍에 있어서도, 한 프로세스는 계속 놀고 있을 수 있음.  이럴 때 적합..
< findAndModify > 는 아이템을 리턴하고 업데이트를 한 조작내에서 가능.
리턴된 놈은 업데이트 전이지만, 컬렉션에서 찾아보면 업데이트가 되어있슴.
<삭제 : “remove” : true … >도 가능..

Key of findAndModify
findAndModify
query
sort
update
remove
new

매칭 다큐가 없으면 에러.
한 개의 다큐만 가능.
<업서트> 로 사용 불가.  기존의 다큐만 수정 가능.
속도 : find, update, getLastError 를 연속 실행할 때 만큼 느림.

The Fastest Write This Side of Mississippi [p41]

삽입, 제거, 업데이트는 보내고 잊어버리는 타입. 빠르다. fire-and-forgot
로그 기록 등에서는 무방하나 결재 시스템에서는 허용할 수 없음.

Safe Operations

관계형 디비 위의 어플리케이션중 많은 부분이 리턴 코드를 확인 안함. 몽고는 디폴트로 체크하지 않음.
Safe version 은 getLastError 명령어를 실행함. 드라이버는 디비 반응을 기다리고 적당한 에러를 핸들하고 예외를 던짐.
성공하면 그에 따르는 정보를 포함함.

Catching “Normal” Errors

Safe operation 은 ‘이상한’ 디비 행동을 디버그 하는 방법이기도 함.  개발중에는 널리 사용해야 함. 여러 에러를 방지할 수 있음.  가장 흔하게는 중복 키 에러.
중복키의 경우 삽입 실패를 모르고 넘어갈 수 있음.

Requests and Connections

몽고디비 서버의 각 연결마다 디비는 연결의 요청에 따른 큐를 생성한다. 클라이언트가 연결에 요청하면 큐의 끝에 놓여지고, 다음의 요청은 큐에 있는 작업이 실행된 후에 실행된다. 그러므로, 단일 커넥션은 디비의 consistent view 를 갖고 자신의 쓰기를 읽을 수 있다.
이것은 per-connection queue. 쉘을 두개 열면 이것은 2개의 연결임. 한쪽에서 넣은 후에 다른쪽에서 읽으면 리턴 못받음. 하지만, 한 쉘에서는 삽입 후 쿼리는 리턴 함.  수작업으로는 재현 힘들지만 바쁜 서버에서는 가능한 얘기.
한 쓰레드에서 작업하고 다른 쓰레드에서 확인하는 것은 무의미.   특히, 루비, 파이썬, 자바 드라이버에서.   => connection pooling 사용.

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중