몽고DB 기본

빅데이터 2016. 2. 23. 12:15

1. mongodb 기본


가. 문서단위의 데이터베이스
페타바이트(1015) 수준의 데이터에 처리를 위한 솔루션으로 한군데서 처리하기 힘드므로 서버 여러 대로 나누어서 분산 처리한다.
NoSQL은 높은 확장성을 지원하지만 관계형 데이터베이스처럼 데이터의 무결성과 정합성을 보장하기는 힘들다.
MongoDB는 구조화되지 않은 문서 중심으로 정보를 관리한다.


나. 특징

1) 고급 수집용 Map/Reduce 구현을 지원한다.
auto-sharding과 복제, 맵리듀스는 한 개의 세트로 구성되며, 여러 군데 분포된 데이터를 모아서 구성하고 사용할 수 있게 해준다.

2) 대용량 파일 저장을 위한 GridFS를 사용한다.

3) 관계형 데이터베이스 속성 색인 기능이 있다.

4) 자동 샤딩(auto-sharding)
가상의 큰 테이블을 만들고 데이터를 집어넣는 과정으로 무작위로 디스크에 데이터를 입력하는데, 디스크에 오류가 발생하면 데이터가 유실될 수도 있으며 대안으로  Replica set이 있다. (수평적 확장)

5) master/slave 복제를 지원한다.

6) collection 기반 객체 저장

7) in-place update 기능을 지원

8) 집합 프레임워크(Aggregation Framework)
집합 작업을 할 때 복잡한 함수 정의와 함께 맵리듀스를 시행하지 않도록 해준다.


다. 데이터 모델링


1) 비정규화(Denormalization)    
쿼리 최적화, 여러 문서나 테이블에 같은 데이터를 복사하는 것


2) 집합
키-값 저장소와 그래프 데이터베이스는 일반적 값에 대한 제약 조건을 배치하지 않기 때문에, 임의의 형식으로 구성가능


3) 조인
조인은 NoSQL에서는 거의 지원되지 않으며 비정규화와 집합을 사용해서 조인을 대신하거나 프로그램에서 처리


4) 원자적 집합
NoSQL은 트랜잭션 지원을 제한한다. ACID를 위해 집합(Aggregation)을 사용  

ACID(트랜잭션 안전수행을 위한 원자성, 일관성, 고립성, 지속성: Atomicity, Consistency, Isolation, Durabillity)


5) Enumerable의 키
키-값 데이터 모델을 정렬할 때 키를 해싱 하여 여러 서버에 분할 할 수 있다.


6) 차원 축소(Dimensionality reduction)     
키-값 또는 다차원 모델의 데이터 매핑기술로서 지리 정보 시스템에서는 색인 쿼드 트리나 R-트리의 일부 변형을 사용한다.


7) 색인 테이블
접근 패턴에 따라 특수 테이블을 만들고 유지하는 것으로 사용자 ID가 접근할 수 있는 사용자 계정을 저장하는 마스터 테이블이 있다. 이렇게 특수 테이블을 사용하면 사용자를 검색하는 질의는 핵심이며, 질의에 따라 별도의 추가 테이블을 사용할 수 있다.
색인 테이블은 마스터 테이블의 배치 모드를 사용하여 갱신할 수 있다. 단 별도의 특수 테이블을 사용하여 추가적인 성능 저하와 갱신으로 인한 일관성 문제가 발생할 수 있다.


8) 복합 키 색인   
하나 이상의 컬럼을 pk로 지정하는 방법으로 정렬된 키 저장 방식을 사용할 때 매우 유용하다. 차원 축소기법과 유사하고 다차원 색인 기법을 제공한다.


9) 복합키를 사용한 집합
복합 키는 색인에 사용할 수도 있지만, 서로 다른 타입을 가지는 그룹 만들기에도 사용할 수 있다. 복합 키는 다른 타입의 그룹을 만들기에도 사용한다.


10) 중첩 세트   
중첩된 세트 모델의 트리 같은 구조를 위한 기술


11) 배치 그래프 처리
분산 그래프 처리 맵리듀스와 설명된 메시지 전달 패턴을 사용하여 수행할 수 있다.


라. MongoDB 데이터 모델링

1) 시간이 지날수록 성장하고 변경되는 데이터

2) 응용 프로그램에 따른 질의

3) 색인 전략

4) BSON의 배열 데이터 (BSON: Binary JSON, JSON 문서를 바이너리로 인코딩한 포맷)


ex) json

( name:"kim", age:10 },

( name:"lee", age:10 }


마. 데이터베이스 상태 정보

1) db : 현재 사용 중인 데이터베이스


db.stats() 이라고 친 뒤 플레이 버튼 누른다. (robomongo에서 option-text mode로 바꾸고 아래에서 확인.)



2) collection

데이터베이스에 정의된 컬렉션의 수


3) objects
모든 컬렉션에 정의된 문서의 개수


4) avgObjSize
각 문서의 평균 크기를 나타낸다.


5) dataSize
데이터베이스에 포함된 모든 데이터의 총 크기


6) storageSize
데이터베이스에 정의된 모든 컬렉션에 할당된 바이트 공간을 나타낸다.


7) indexeas
컬렉션에 정의된 모든 색인의 개수를 나타낸다.


8) indexSize
데이터베이스의 모든 색인이 차지하는 바이트 크기를 나타낸다. 색인이 램에 상주해 있을 때 데이터베이스 성능이 빨라지므로 성능을 튜닝 할 때 이 값을 유의해서 살펴볼 필요가 있다.


9) fileSize
데이터베이스에 할당된 총 바이트 크기를 나타낸다.


바. ObjectId
고유 아이디는 12바이트로 표현된다.

5250bbef f178e7 7ff8 b71009 <-- [타임스탬프 서버ID 프로세스ID 로컬카운터] 형식
5250bbef : 타임스탬프(4byte 유닉스 에포크로 1970년1월1일 이후 시간을 나타낸다)
f178e7 : 서버ID (3byte)
7ff8 :프로세스 ID(2byte)
b71009 :로컬 카운터(3byte 랜덤 값으로 시작하며 문서에 id가 생성될 때마다 증가하는 카운터)


사. BSON 데이터 타입 (bsonspec.org)
BSON은 Bianry JSON의 약어로 JSON 문서를 바이너리로 인코딩한 포맷이다. MongoDB에서 최초로 제안하였으며, 주로 JSON 데이터를 저장하거나 네트워크로 전송하기위해 바이너리 포맷으로 변경하는데 사용한다. BSON 타입은 JSON 구조에 바이너리 데이터를 추가할 수 있는 이점이 있다.


1) \x01 : double

2) \x02 : String (utf-8 문자열)

3) \x03 : Object (문서)

4) \x04 : Array (배열)

5) \x05 : Binary Data(바이너리 데이터)

6) \x06 : 사용되지 않음

7) \x07 : ObjectId

8) \x08 : Boolean

9) \x09 : Date

10) \x0A : NULL

11) \x0B : 정규 표현식

12) \x0C : 제거됨(DBPointer)

13) \x0D : JavaScipt (JavaScript코드)

14) \x0E : 제거됨(Symbol)

15) \x0F : JavaScript(w/scope 유효번위를 포함)

16) \x10 :32-bit integer

17) \x11 : Timestamp

18) \x12 : 64-bit integer

19) \x13 : Min key

20) \x14 : Max Key


아. 데이터 타입별 정리

1) 숫자
double, int, long 타입을 지원하고 javaScript에서는 Number 하나로 숫자를 정의한다. 

NumberInt() , NumberLong()을 사용하며 별도의 함수를 사용하지 않으면 double형으로 저장된다.     


2) 문자타입
UTF-8 타입으로만 사용된다.


3) 시간타입
64비트 정수로 표현되는 timestamp를 지원     

 

4) 날짜타입
64비트 정수형으로 유닉스 에포크 이후 소요된 시간을 밀리 초로 나타낸 값이다.


5) ObjectId  
12바이트로 구성되며 처음 4바이트를 생성 시점의 타임스탬프


자. 대규모 삽입하기 
insert문으로 많은 수의 데이터를 입력할 때는 ContinueOnError (기본 값 false)에 true를 지정하여 삽입 중 에러가 발생해도 계속 진행하도록 하는 것이 좋다. PHP의 경우 batchInsert()라는 함수 제공




2. MonhoDB의 query


가. mongoDB 용어정리 
database               /database
collection               /table
document(BSON)       /row
field                    /column
index                   /index
table join               /내장 문서&linking
primary key            /primary key
aggregation(집합)       /group by(집합)


나. 컬렉션 구조
기존 관계형 데이터베이스는 User, Category, Article, Comment등을 분리해서 유지하지만 

mongoDB는 User, Article({Comment, Tag[], Category[]} )와 같이 하나의 document에 포함하려는 특성이 있다.




3. collection


가. 정의
문서들을 담는 저장소


나. collection 생성 명령

collection 이름의 첫 글자는 반드시 알파벳과 숫자로 시작 두 번째 글자부터는 알파벳과 숫자, 온점(.)을 사용한다.
db.createCollection("sample1");
db.createCollection("sample2", {size:204800}) // 204800 byte 크기지정


다. collection 상태 확인
db.sample1.stats()


라. collection 조회 명령
show collections


마. 명령들
db.sample1.renameCollection("product")
db.product.drop()
collection은 문서 삽입 시점에서 자동으로 생성


바. 제한 컬렉션(Capped collection)
높은 성능의 로깅 기능을 위해 설계된 고정 크기의 컬렉션 새로운 데이터를 삽입할 때 공간이 없으면, 오래된 무서부터 덮어 쓴다. 빈 공간을 관리하지 않기 때문에 삽입 속도가 빠르다. _id 필드를 기본으로 생성자지 않으며 색인이 없기 때문에 insert시간이 적으며 _id필드가 필요하면 수동으로 지정 가능 
개별 문서를 지우거나 갱신하는 연산을 수행 할 수 없다.

1) db.createCollection("log",{capped:true, size:100000})

2) db.createCollection("log",{capped:true, size:5242880, max:5000})
size : 문서의 크기 
max : 최대 문서 개수

3) db.log.isCapped() 제한 컬렉션인지 확인

4) db.runCommand({"convertToCapped":"sample", size:1000000}) // 제한 컬렉션으로 변경

5) db.product.find().sort({$natural:-1})
제한 컬렉션은 삽입 순서가 저장된 순서이기 때문에 natural order를 사용할 수 있고 역순으로 정렬하려면 -1로 지정한다.

6) db.users.remove()
db.users.remove({firstname:"suhwan"}) // firstname이 suwan인 데이터 삭제


사. 데이터 조작


1) 기본 명령어

가) 생성 db.collection.insert()

나) 조회 db.collection.find()

다) 수정 db.collection.update()

라) 삭제 db.collection.delete()


robomongo에서 open shell 후 아래와 같이 입력.


db.users.insert([

{"name":"kim","age":10},

{"name":"lee","age":11},

{"name":"choi","age":20},

{"name":"park","age":22},

])


F5키를 누르면 위의 명령이 실행된다.

Inserted 1 record(s) in 106ms


db.users.find() 로 내용 조회 가능.


/* 1 */

{

    "_id" : ObjectId("56ccfc236d9647b22b587c02"),

    "name" : "kim",

    "age" : 10

}


/* 2 */

{

    "_id" : ObjectId("56ccfc236d9647b22b587c03"),

    "name" : "lee",

    "age" : 11

}


/* 3 */

{

    "_id" : ObjectId("56ccfc236d9647b22b587c04"),

    "name" : "choi",

    "age" : 20

}

.

.

.



2) 데이터의 검색(find)

가) 프로젝션
필드를 지정하는데 사용된다.
db.collection.find( {user_id:{$lt:42}, {history:0}) 

// user가 42보다 큰 데이터를 find하고 history필드는 감춘다.(1이면 display, 0이면 hidden)


db.users.find({}, {name:0}) 이름을 보이지 않게 하고 검색


나) $elemMatch
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
배열 내 특정 필드에 대한 조건을 지정한다.
db.schools.find({zipcode:63109},
{students:{$elemMatch:{school:102,age:{$gt:10}}}})


다) $slice
db.collection.find({field:value}, {array:{$slice:count}})
배열 필드에서 반환되는 요소의 개수를 제한한다.
db.schools.find({},{students:{$slice:5}}) 배열열에서 5개의 요소만 find 
db.schools.find({},{students:{$slice:-5}}) 배열의 끝에서 5개의 요소
db.schools.find({},{students:{$slice:[20,10]}}) 처음 20개는 건너뛰고 그 다음 10개 반환
db.schools.find({},{students:{$slice:[-20,10]}}) 뒤에서 20개를 건너뛰고 그 위치에서 다음 10개


라) 수식어

(1) $query 
질의를 기술하는 수식어 다음 두 명령은 결과가 같다
db.collection.find({$query:{age:25}})
db.collection.find({age:25})


(2) $comment
데이터베이스 프로파일러 로그에 기록될 내용을 주석으로 추가한다.
db.collection.find($query:{<query>},$comment:<comment>})


(3) $explain
질의를 수행하기 위해 준비된 실행 계획을 출력한다. 최적화에 사용한다.
db.collection.find($query:{}, $explain:1})


(4) $hint
특정 필드를 색인으로 사용하도록 강제 지정
db.users.find({$query:{}, $hint:{age:1}})


(5) $maxScan
질의가 가져오는 문서의 개수를 제한한다.
db.collection.find({$query:{<query>}, $max : {field1: <maxValue1>, ... fieldM: <max valueN> }})


(6) $max
질의에 대해 최댓값 색인으로 적용하는 값이다.
db.collection.find({$query:{<query>}, $max:{field1:<maxvalue1>, ... fieldN:<max valueN>}


(7) $min
질의에 대해 최소값 색인으로 적용하는 값
db.collection.find({$query:{<query>}, $min:{field1:<minvalue1>,...fieldN:<min value>}})


(8) $orderby
정렬결과를 반환한다. 내림차순을 -1 오름차순은 1과 양수로 지정한다.
db.collection.find({$query:{},$orderby:{age:-1}})


(9) $showDiskLoc
해당 문서가 저장된 실제 파일 위치 정보를 가져와 보여준다.
db.collection.find({$query:{<query>},$showDiskLoc:true})


(10) $snapshop
스냅샷 모드로 동작해 하나의 문서를 한 번만 반환하도록 한다. 문서가 새로 생성되거나 삭제되는 경우 반환될 수도, 안될 수도 있다.
db.collection.find({$query:{}, $snapshop:true})


3) 쿼리와 커서 
쿼리를 해서 문서를 차례로 가져오는 작업을 하려면 cursor를 사용해야 한다.


가) cursor.addOption()
특정 프로토콜 플래그를 정의할 때 사용한다. 드라이버별로 달라질 수 있다.
var t = db.myCappedCollection;
var cursor = t.find().addOption(DBQuery.Option.tailable).
                   addOption(DBQuery.Option.awaitData)


나) cursor.count()
커서에 의해 반환된 문서의 개수를 가져혼다.
db.orders.find().count()
// ord_dt 필드 값이 2013년 11월01일보다 큰 문서의 개수
db.orders.find({ord_dt:{$gt:new Date(11/01/2013')}}).count()


다) cursor.explain()
수식어에서 $explain과 대응하는 함수로, 질의를 최적화할 때 유용하게 사용되는 질의 실행 계획을 출력한다.
db.collection.find().explain()
// 특정 필드에 색인을 걸었을 때의 질의 실행 계획
db.products.find().hint({type:1}).explain()


라) cursor.forEach()
커서로부터 반환된 각 문서를 반복해서 가져오는 Javascript형식의 함수이다.
db.users.find().forEach(
    function(myDoc){
            print("user: " +myDoc.name);
    }
);

마) cursor.hasNext()
find()로부터 반환된 커서가 반복문 내에서 다음 문서가 있는지 확인할 때 사용하는 함수


바) cursor.hint()
수식어에서 $hint와 대응하는 함수로, 강제로 특정 필드를 색인으로 사용하도록 지정한다. 현재 컬렉션의 색인을 확인하는 명령은 db.collection.getIndexes()


사) cursor.limit()
$maxScan과 대응하는 함수로, 반환되는 결과 세트의 최대 크기를 제한한한 0으로 지정하면 제한이 없는 것으로 간주한다.


아) cursor.map()
커서가 가지는 모든 결과 세트에 대해 특정 값을 추출해 배열로 구성해 반환한다.
db.users.find().map(function(u) {return u.name;});


자) cursor.max()
$max와 대응하는 함수로 질의 조건으로 최댓값을 지정할 수 있다. 최댓값을 지정하려면 특정 색인을 기준으로 정렬되어 있어야 하므로 hint()를 함께 사용해서 특정 필드를 색인으로 지정해야 한다.
db.products.find().max({price:1.99}).hint({price:1})


차) cursor.min()
$min과 대응하는 함수로 질의 조건으로 최솟값을 지정할 수 있다. hint()와 함께 사용해야 한다.
db.products.find().min({item:'apple', type:'jonagold'}).hint({item:1, type:1})


카) cursor.next()
커서에서 다음 문서를 가져오는 함수


타) cursor.showDiskLoc() 
해당 문서가 저장된 실제 파일 위치 정보를 가져혼다.


파) cursor.skip() 
커서에서 원하는 수만큼 건너뛰기 한 이후부터 문서를 가져온다.


하) cursor.size()
커서로부터 반환되는 전체 문서 크기를 반환한다. cursor.skip()과 cursor.limit() 함수 결과를 반영한 이후의 값이다.


거) cursor.snapshop()
커서가 _id 필드를 강제로 색인화 해서 사용하게 하고 _id 필드를 기준으로 문서가 단 한번만 반환되도록 한다.


너) cursor.sort()
수식어에서 $orderby와 대응하는 함수로 오름차순이나 내림차순으로 정렬한 결과를 반환한다. 내림차순은 -1로 오름차순은 1로 지정한다.


더) cursor.toArray()
결과로 반환된 문서를 배열로 변환해서 가져오는 함수이다.
var allProductsArray = db.products.find().toArray()
if(allProductsArray.length > 0){
   printjson ( allProductsArray[0])
}


4) find()
db.collection.find(<criteria>, <projection>)
criteria : 조건문
project: 프로젝션 연산자 
db.schools.find( {},{ _id:0, zipcode:1, "students.name":1},
  {students:{$elemMatch:{school:102,age:{$gt:10}}}}
) // 배열 안에 항목도 "student.name":1 과 같은 식으로 출력 여부를 결정 할 수 있다.
findOne()
문서 중 하나만 반환
// G로 시작하면서 2000년01월01일 보다 적은 
db.bios.findOne({
   $or: [
     {'name.first' : /^G/ },
     {birth:{$lt:new Date('01/01/2000')}}
     ]
}
)


가) 쿼리 선택자


(1) 비교 선택자


(가) $gt
질의에 정의된 값보다 큰 값
db.users.find( {age : {$gte : 20, $lt : 30}}),
{age:{$gte:20}, age : {$lt:30}} // 둘 중에 하나만 실행된다.


(나) $gte
질의에 정의된 값보다 크거나 같은 값


(다) $in
질의에 정의된 값 배열 중 하나와 일치하는 값

{ qty: {$in : [5,15] } }


(라) $lt 
질의에 정의된 값보다 작은 값


(마) $lte
질의에 정의된 값보다 작거나 같은 값


(바) $ne
질의에 정의된 값과 같지 않은 값


(사) $nin
질의에 정의된 값 배열에 포함되지 않는 값


(2) 논리 선택자 
v1.6부터 추가됐으며 v2.0부터 중첩 사용이 가능하지만 중첩 사용은 성능이 떨어지는 단점이 있다.


(가) $or
두 가지 이상의 조건 절 중 하나가 참인 조건
{ $or : [ { <expression> },{ <expression2>}, ... , {<expressionN>} ]}
$or : [ {qty:{$lt:20}}, {sale:true} ]


(나) $and
두 가지 이상의 조건 절 모두 참인 조건


(다) $not
주어진 조건 절에 맞지 않는 조건


(라) $nor
두 가지 이상의 조건 절 모두 맞지 않는 조건


(마) 요소 선택자

① $exist 
특정 필드를 포함하는 조건
db.users.find({color:{$exists:false}}) // color 필드가 없는 객체 조회
db.users.find({color:null}) // exists:false 와 같은 결과 
db.users.find({color:{$ne:null}}) // exists:true과 같은 결과

② $type
주어진 필드가 특정 필드인 조건
db.users.find( {age : {$type : 1}})


(바) 평가 선택자

① $mod
주어진 필드의 값이 나누기 연산의 값인 조건 
db.users.find( {age : { $mod : [4, 0] } } )  // 4로 나눈 나머지가 0


② $regex
정규 표현식과 일치하는 조건 
db.users.find( {name :{$regex:/kim|lee/i}} )


③ $where 
javaScript의 조건문에 일치하는 조건
성능상의 문제로 일반 연산자로 안 되는 경우만 사용 
db.users.find( {$where : "function() { return this.age == 10; }" }  )


(사) 배열 선택자

① $all
주어진 조건의 모든 요소를 포함하는 배열
{ <field>: { $all: [ <value1> , <value2> ... ] } }
db.students.find( {group: {$all:["ski","swim"]}} )


② $elemMatch
주어진 조건의 모든 요소와 일치하는 배열
{ <field>: { $elemMatch: { <query1>, <query2>, ... } } }
db.schools.find(
  {students:{$elemMatch:{school:102,age:{$gt:10}}}}
)
db.schools.find( 
{ students : { $elemMatch: {name:"john", age:10 } } } 
)


③ $size
주어진 크기 조건과 일치하는 배열 
db.students.find( {group: {$size:2}} )


(3) update()

(가) db.collection.update(
       <query>,
       <update>,
       {
       upsert:<Boolean>,
       multi:<Boolean>
       }
)


(나) 옵션

① multi : 다중 문서를 갱신하는 옵션

② upsert : 아이템이 있으면 갱신하고 없으면 새로 추가


(다) 갱신 선택자

① $inc : 필드 값의 수치를 증가하거나 감소시킨다.
db.books.update( {author:"Dante"}, { $inc : {price:1} }  )  // price를 1증가 시킨다.

② $remane : 필드의 이름을 변경한다.
db.books.update ({author:"Dante"},{ $rename : {"quantity":"price"} } )

③ $setOnInsert : upsert 옵션으로 새로운 무서가 추가될 때, 기본 필드 값을 설정한다. 기존 문서를 갱신할 때는 사용되지 않는 값이다.

④ $set  기존 문서를 갱신할 때 사용되는 값이다.

⑤ $unset 기존 문서에서 특정 필드를 제거한다.


(라) 배열 갱신 선택자

① $addToSet : 기존 배열에 해당 값이 없을 때만 해당 필드와 값을 추가한다.

② $pop : 배열의 첫 번째나 마지막 요소를 제거한다.

③ $pullAll : 배열에서 여러 요소의 값을 제거한다.

④ $pull : 조건에 맞는 요소를 가져와 해당 요소를 제거한다.

⑤ $push : 배열에 요소를 추가한다. 해당 필드가 없으면 오류 발생


나) 집합연산

(1) count()
조건에 맞는 문서의 수를 반환한다.


(2) distinct()
중복되지 않는 값을 반환한다.


(3) group()
관계형 데이터베이스의 group by 와 유사한 동작을 수행한다.


(가) 옵션

① key : 그룹으로 묶을 필드의 이름. 복합키로 지정할 수도 있다. keyf를 사용하지 않으면 반드시 사용해야 하는 옵션

② reduce : 그룹으로 묶은 문서에 집합 연산을 수행하는 함수이다. 이 함수는 보통 어떤 값의 총합을 반환한다. 현재 문서와 집합결과 두 개를 매개변수로 필수로 입력해야한다.

③ initial : reduce() 함수가 처음 실행될 때 두 번째 매개변수로 전달받는 집합 결과를 지정하는 문서에 대한 초기 값을 지정한다.

④ keyf : key필드를 대체하여 사용할 수 있는 옵션으로, key 객체를 설정하는 Javascript함수이다.

⑤ cond : 컬렉션 전체에 대해 그룹 동작을 수행하는 것이 아니라 특정 조건에 맞는 문서에 대해서만 그룹 동작을 수행하고 싶다면 이 옵션으로 조건을 지정한다.

⑥ finalize : 결과 세트를 반환 할 때 최종 결과 값을 계산하기 위한 옵션이다. 이 결과 값으로 기존의 결과 문서를 수정하거나 대체할 수 있다.


(4) 맵리듀스(MapReduce) 함수
MapReduce란 구글이 많은 자료를 여러 대의 컴퓨터에서 병렬로 계산하려고 만든 프레임워크이며, 하둡도 맵리듀스 구현체이다.


(가) 맵리듀스(MapReduce) 처리 방식   
map(key, value)
임의의(key, value)를 읽어서 이를 필터링하거나 다른 값으로 변환한 다음, 다른(key2, value2)에 대응한다.
reduce(key2, list_of_value2)
key2를 기준으로 취합된 value2값을 읽어서 집합 연산을 수행한 다음, 최종 결과인 total 값을 생성한다.


(나) RDBMS와 맵리듀스의 차이

① 데이터 크기 :  GigaBytes <=>  petabytes

② 처리방식 :     대화형및 일괄처리 <=> 일괄 처리

③ 갱신 :          여러 번 읽고 쓰기 <=> 한번 쓰고 여러 번 읽기

④ 구조 :          고정 스키마 <=> 동적 스키마

⑤ 무결성 :       높음 <=> 낮음

⑥ 확장성 :       비선형 <=> 선형


(다) 맵리듀스의 장점과 단점

① 장점 : 단순하고 사용이 편리하다. 처리가 유연하고 독립적인 저장 구조로 내구성이 뛰어나며 확장성도 높아서 여러 노드로 확장할 수 있다.


② 단점 : 그룹화 하여 집합하는 방식이 아닌 다른 연산이 필요한 경우에는 효율적이지 않을 수 있다. 
고차원 언어에 대한 지원이 없어서 스키마에 의해 데이터 무결성을 보장하지 못한다.
RDBMS보다 단위 시간당 작업 처리량이나 시스템의 효율성에서 낮은 성능을 보이기도 한다.
맵리듀스는 40여 년의 역사를 가진 RDBMS와 비교하면 신생기술이다. 성능 등에서 부족한 점이 있으므로 대용량 데이터 처리에 특화되어 사용해야할 기술로 판단된다.


(라) 맵리듀스 집합 함수
맵리듀스 함수는 group함수가 나오고 나서, 분산된 데이터를 처리하고자 추가된 함수이다. 어찌 보면 group 함수보다 좀 더 유연한 버전으로 생각할 수도 있다.

① 형식
       db.collection.mapRecude(
       <map>,
       <reduce>,
       {

                        out:<collection>,

                        query:<document>,

                        sort:<document>,

                        limit:<number>,

                        finalize:<function>,

                        scope:<document>,

                        jsMode:<boolean>,

                        verbose:<boolean>

                        }               

                        )


(마) 맵리듀스 함수의 옵션

① map : 지정된 key로 그룹화 하여 value를 수집하는 맵 함수를 정의한 JavaScript 함수이다. 집합에 사용할 key와 value를 위해 emit()함수를 여러 번 호출할 수 있으며, 한 번도 호출하지 않을 수도 있다. this는 현재 문서를 의미하며, emit() 함수 내에서는 데이터베이스에 직접 접근할 수 없다.


② reduce : key와 value 목록을 전달받아 반복적인 집합 연산을 수행하는 JavaScript 함수이다. 함수의 결과값은 항상 전달받은 value와 같은 구조를 가져야 한다. 함수 내에서는 읽기 연산을 포함한 모든 데이터베이스에 접근을 허용하지 않는다.


③ out : 명령의 결과를 어떻게 반환할지를 정의한다. 모든 결과를 반환하는 것은 {inline:1} 이며, 최대 16MB까지만 반환한다. 또는 결과값을 저장하는 컬렉션ㅇ르 지정할 수 있다. 이때 총 3가지 옵션을 함께 지정할 수 있다. 예를 들어, replace 옵션은 컬렉션에 결과를 덮어쓰고, merge 옵션은 기존 결과에 새로 생성된 결과를 통합하며, recude 옵션은 기존 결과에 reduce를 적용해서 집합을 다시 수행한다.


④ query : 맵리듀스 함수를 적용한 문서를 필터링하는 조건이다.


⑤ sort : 질의에 추가로 적용하는 정렬 조건이다. 이는 맵리듀스 함수의 성능 최적화에 사용된다. 예를 들어, 문서를 정렬하면 중복된 key가 같은 공간에 배치되므로 하나의 노드에 같은 key의 문서가 할당될 확률이 높아 추후 reduce 연산이 줄어들 수 있다.


⑥ limit : 질의에 추가로 적용하는 조건으로 대상 문서의 최대 개수를 지정한다. sort() 함수를 수행하고 limit() 함수를 사용하면, 최근 10,000개의 문서에서 맵리듀스를 수행하는 등의 연산을 할 수 있다.


⑦ finalize : map과 reduce함수의 수행이 끝나고 최종 연산을 수행해 결과 문서에 적용하는 JavaScript함수이다.


⑧ scope : map과 recude, finalize 함수에서 참조하는 전역 변수를 설정한다.


⑨ verbose : true면 소요된 시간 정보를 가져오는 옵션이다.


'빅데이터' 카테고리의 다른 글

MongoDB 설치하기~Robomongo 설치  (0) 2016.02.23
빅 데이터(big data)  (0) 2016.02.23
Posted by netyhobby
,