29
MongoDB 완벽가이드 7장 : 고급 기능 (Advanced Topics) 아꿈사 http://cafe.naver.com/architect1 최성기 [email protected]

[110730/아꿈사발표자료] mongo db 완벽 가이드 : 7장 '고급기능

Embed Size (px)

Citation preview

MongoDB 완벽가이드 7장 : 고급 기능 (Advanced Topics)

아꿈사 http://cafe.naver.com/architect1

최성기 [email protected]

1. DB 명령어

2. 제한 컬렉션

3. GridFS

4. Server-side 스크립팅

5. DBRef : 데이터베이스 참조

7장 ‘고급기능’은

아래 5가지 주제에 대해 설명한다.

1. DB 명령어

2. 제한 컬렉션

3. GridFS

4. Server-side 스크립팅

5. DBRef : 데이터베이스 참조

1. DB 명령어 - db.runCommand(…).. 수행 원리와 대표 명령어들.

db.runCommand( { 명령 문서 } )

이런 형식의 명령어를 3장에서 이미 만났던 적이 있다.

{ getLastError : 1 }

마지막 명령어로 영향받은 문서의 수를 확인

{ findAndModify : ‘…’, ... }

한 번의 연산으로 문서를 찾고 수정한다.

그 뒤로도 매 장마다 이미 신나게 사용함. 아이 씐나 ~

쉘에서 함수 형태로 제공되는 다른 명령어들도 내부적으로는 db.runCommand()를 거쳐서 실행된다.

함수형 명령 db.test.drop()

runCommand 명령 db.runCommand( {“drop” : “test”} )

> db.runCommand({"drop" : "test"}); { "nIndexesWas" : 1, "msg" : "indexes dropped for collection", "ns" : "test.test", "ok" : 1 (책에는 true로 나온다) }

> db.test.drop() true

책이 쓰인 시점에서 명령어는 약 75개, 자료 작성시점 1.8.2 버전 기준으로 약 100여 개가 된다.

shell 명령어 확인 : db.listCommands() 관리자 웹페이지 : http://localhost:28017/_commands

너무 휙 지나감. 볼 수가 없어… 웹페이지 도움말이 펴놓고 참고하기 좋다.

유용한 명령어들만 몇 개 모아보자면…

{ “collStats” : 컬렉션 이름 } 컬렉션 데이터 크기, 할당 공간 용량, 인덱스 크기 통계.

{ “ping” : 1 } 서버가 살아있는지 확인. 잠금 상태여도 바로 리턴된다.

{ “renameCollection” : 컬렉션 이름, “to” : 새 이름 } 컬력션 이름을 변경한다.

{ “repairDatabase” : 1 } { “serverStatus” : 1 } DB 복구 명령 / 서버 모니터링 통계 수치. 8장에서 다룬다.

1. DB 명령어

2. 제한 컬렉션

3. GridFS

4. Server-side 스크립팅

5. DBRef : 데이터베이스 참조

2. 제한 컬렉션 - Capped Collections : 사이즈가 고정된 특수한 컬렉션.

제한 컬렉션은 circular queue처럼 동작한다. 크기 고정. 가득 찬 상태에서 문서 추가 시 가장 오래된 문서가 삭제된다.

공간이 있을 때는 입력 순서대로 들어가다가... 큐가 꽉 차면 가장 오래된 문서가 새 문서로 대체된다.

- 문서 삭제 불가능.

- 문서 수정 불가능.

- 색인 생성 불가능.

제한 컬렉션의 제약

… 결국 데이터를 추가 하고 (순서대로) 읽어내는 데에만 특화.

- 입력 속도가 매우 빠르다. 추가공간 할당/관리 등이 필요 없음.

- 입력 순서대로 뽑는 쿼리가 매우 빠르다.

이미 디스크상에 입력 순서대로 존재하고 있기 때문.

- Age-Out(에이지 아웃) 오래된 데이터는 자동으로 제거.

제한 컬렉션의 속성

제한 컬렉션의 생성

db.createCollection( 컬렉션이름, { capped:true, size:100000 } );

db.createCollection( 컬렉션이름, { capped:true, size:100000, max:100 } );

일반 컬렉션은 자동으로 생성되기도 하지만 제한 컬렉션은 꼭 명시적으로 생성 되어야 한다.

제한 컬렉션의 생성

db.runCommand( { “convertToCapped” : 컬렉션이름, size : 10000 } )

이미 존재하는 일반 컬렉션을 제한 컬렉션으로 변환하는 것도 가능하다.

자연스럽게 정렬하기 - sorting as natural : 입력 순서나 입력 반대 순서로 매우 빨리 정렬.

문서 입력 순서 { “$natural” : 1 }

> db.my_collection:find().sort( { “$natural” : 1 } );

입력 반대 순서 { “$natural” : -1 }

꼬리를 무는 커서 - Tailable Cursors

결과를 모두 꺼냈을 때도 종료되지 않는 커서.

새 데이터가 추가되면 바로 새로운 결과를 꺼낼 수 있다.

제한된 컬렉션에서만 사용 가능.

드라이버마다 사용법은 조금 다르다.

1. DB 명령어

2. 제한 컬렉션

3. GridFS

4. Server-side 스크립팅

5. DBRef : 데이터베이스 참조

3. GridFS - 파일 시스템 : MongoDB에 대용량 이진파일 저장하기.

GridFS의 장점

어플리케이션 구조 단순화 파일 저장을 위한 다른 아키텍쳐를 사용할 것 없이 한 저장소에 같이 저장.

복제, 자동 조각화 사용 가능 DB를 위한 복제/조각화 기능 이용 가능. 장애 복구와 분산 확장에 용이.

특정 파일시스템의 문제를 피한다. 같은 디렉터리에 대량의 파일을 저장해도 문제가 발생하지 않는다.

높은 디스크 지역성(locality) 2Gb 청크로 데이터파일을 할당.

mongofiles.exe GridFS 유틸리티

커맨드라인 명령으로 GridFS를 다룰 수 있다.

D:\> mongofiles put foo.txt connected to: 127.0.0.1 added file: { _id: ObjectId('4c0d2a6c3052c25545139b88'), filename: "foo.txt", length: 13, chunkSize: 262144, uploadDate: new Date(1275931244818), md5: "a7966bf58e23583c9a5a4059383ff850" } done! D:\> mongofiles list connected to: 127.0.0.1 foo.txt 13 D:\> mongofiles get foo.txt connected to: 127.0.0.1 done write to: foo.txt

gridfs_offset gridfile_write_file(gridfile* gfile, FILE* stream); void gridfile_write_buffer( gridfile* gfile, const char* data, … );

각 언어별 드라이버마다 GridFS를 다루는 인터페이스 제공.

C 인터페이스의 파일 올리기 :

C++ 인터페이스의 파일 올리기 :

GridFS 대부분의 작업은 클라이언트 드라이버가 처리한다. 서버는 거들 뿐…

binary

fs.files 컬렉션 { 파일 헤더 }

fs.chunks 컬렉션 { 파일 데이터 0 } { 파일 데이터 1 } { 파일 데이터 2 }

: { 파일 데이터 N }

클라이언트 이진 파일

1. DB 명령어

2. 제한 컬렉션

3. GridFS

4. Server-side 스크립팅

5. DBRef : 데이터베이스 참조

4. Server-side 스크립팅 - 서버에서 실행되는 자바스크립트. 저장 프로시저와 유사.

db.eval() 스크립트를 서버에 보내고 결과를 받는다.

> db.eval("return 1;") 1 > db.eval("function() { return 1; }") 1 > db.eval("function(u) { print('Hello, '+u+'!'); }", [username]) null (값을 리턴하는 함수가 아니다. 메시지는 서버 로그에 찍힌다.) > db.eval("function(x,y,z) { return x + y + z; }", [num1, num2, num3]) ...

코드나 함수를 보내면 된다. 인자를 전달해야 할 때 함수를 넘기자.

system.js 자바스크립트 변수를 저장하는 특수 컬렉션

> db.system.js.insert({"_id" : "x", "value" : 1}) > db.system.js.insert({"_id" : "y", "value" : 2}) > db.system.js.insert({"_id" : "z", "value" : 3}) > db.eval("return x+y+z;") 6 > db.system.js.insert({"_id" : "log", "value" :

function(msg, level) { var levels = ["DEBUG", "WARN", "ERROR", "FATAL"]; level = level ? level : 0; // check if level is defined var now = new Date(); print(now + " " + levels[level] + msg); }})

> db.eval("x = 1; log('x is '+x); x = 2; log('x is greater than 1', 1);");

Note: Security 클라이언트가 명령어를 보낼 때, 인젝션 공격 가능성에 주의해야 한다.

> func = "function() { print('Hello, "+username+"!'); }" // username 변수에 “); db.dropDatabase(); print(“가 들었다면… > func = "function() { print('Hello, '); db.dropDatabase(); print('!'); }" > db.eval( func ) 서버로그 : Hello, ! Shell : { “dropped” : my_collection, “ok” : 1 }

대부분의 드라이버는 DB에 코드를 보낼 때 특수 형태를 사용한다. C++ 드라이버엔 없는 듯…? 아무튼 코드 작성자가 신경 써야 함.

1. DB 명령어

2. 제한 컬렉션

3. GridFS

4. Server-side 스크립팅

5. DBRef : 데이터베이스 참조

5. DBRef : 데이터베이스 참조 - 한 문서가 다른 문서를 참조하기 위한 방법 중 하나.

DBRef MongoDB의 문서를 고유하게 식별하고 참조한다.

{ “$ref” : collection, “$id” : id_value } { “$ref” : collection, “$id” : id_value, “$db“ : database }

한 컬렉션 내에서(혹은 다른 DB에서도) 특정 문서를 참조할 수 있도록 하는 내장 문서(embedded document).

{"_id" : 5, "author" : "mike", "text" : "MongoDB is fun!"} {"_id" : 20, "author" : "kristina", "text" : "... and DBRefs are easy, too", "references": [{"$ref" : "users", "$id" : "mike"}, {"$ref" : "notes", "$id" : 5}]}

forign key등의 개념이 약한 점을 위해 뭔가 만드는 중인 듯. 개발 편의를 고려한 기능으로 보이나 아직 많이 모자라다. 책에도 굉장히 자신감 없는 어투로 설명되어있다. (본질적이지 않다. 안써도 된다… -_-;; )

Driver support for DBRef

서버에서는 DBRef에 대한 예외처리가 없는듯. 대부분 클라이언트의 드라이브 구현에 달려있다. 좋은 예 : DBRef로 참조한 문서에서 자동 역참조 지원. 나쁜 예 : DBRef를 내장문서가 아닌 일반 문서로 처리. 그냥 無...

결국 어느 언어로 된 드라이버를 쓰느냐가 중요하다는 건데…

Driver support for DBRef

http://www.mongodb.org/display/DOCS/Database+References 에서 언어별 드라이버의 지원 여부와 정보를 확인할 수 있다.

기대를 저버리지 않고

C++은 지원하지 않는다.

나쁜 예! 그냥 無!...

MongoDB 완벽가이드 7장 : 고급 기능 끄읕.