Unit Four

Save this PDF as:
 WORD  PNG  TXT  JPG

Size: px
Start display at page:

Download "Unit Four"

Transcription

1 MongoDB DB 설계패턴및성능튜닝솔루션 주종면

2 발표자 : 주종면. PLAN 정보기술 / 대표컨설턴트 - 한국데이터베이스진흥원기술위원및겸임교수 - 한국 SW 기술협회겸임강사 - MongoDB Master 공인전문가 - Oracle ACE 공인전문가 - DB 설계 / 튜닝 / 컨설팅. MongoDB 공식한국사용자그룹운영자 현재회원수약 1,530 명 - 초 / 중급스터디그룹및심화스터디그룹운영중 - 10gen co. 엔지니어초빙기술컨퍼런스개최. 미국 10gen co. 한국공식파트너 (Training ) - MongoDB 개발자과정및 DBA 과정운영 - MongoDB 개발및모니터링국산툴개발중 ( 올챙이툴 )

3 - 목차 - 1 장. NoSQL 개념 2 장. Data Modeling & 설계 Pattern 3 장. MongoDB 성능튜닝솔루션

4 1 NoSQL 개념

5 IT 분야 10 대키워드 2011 년 10 대키워드 2012 년 10 대키워드 2013 년 10 대키워드 커머셜클라우드 컨슈머클라우드 & N 스크인 UX 비즈니스플랫폼 NS 스마트워크 상황인식컴퓨팅 보안 / 프라이버시 360 마켓플레이스에코시스템 비즈니스분석기술 멀티플랫폼으로의웹표준 응용프로그램수명주기관리 정보보호및보안빅데이터도입 & 활용클라우드서비스신종보안위협소셜네트워크서비스스마트홈 & 가전서비스모바일애플리케이션특허 & 지재권중요도위치기반서비스클라우드컴퓨팅확산스마트워크 HTML5 도입소셜비지니스소셜미디어 & 엔터프라이즈스마트디바이스차세대반도체 & 디스플레이오픈플랫폼콘텐츠서비스빅데이터신정부의 IT 정책 * 출처 : 한국정보화진흥원동향분석시리즈참조

6 * 출처 : 한국정보화진흥원동향분석시리즈참조

7 Big Data 솔루션 빅데이터의수집과저장기술 NoSQL MongoDB Casandra Hbase 빅데이터의추출과분산기술 Hadoop Storm Spark Kafka 빅데이터의분석및통계기술 R SAS SPSS

8 DBMS for NoSQL

9 NoSQL 제품군 1. Key-Value Database 1) Amazon s Dynamo Paper 2) Data Model : Collection of K-V pairs 3) 제품유형 : Riak, Voldemort, Tokyo* 3. Document Database 1) Lotus Notes 2) Data Model : Collection of K-V collection 3) 제품유형 : Mongo DB, Cough DB 2. BigTable Database 1) Google s BigTable paper 2) Data Model : Column Families 3) 제품유형 : Hbase, Casandra, Hypertable 4. Graph Database 1) Euler & Graph Theory 2) Data Model : nodes, rels, K-V on both 3) 제품유형 : AllegroGraph, Sones * Availablity( 유용성 ), Consistency( 일관성 ), Partitioning( 파티션닝 ) 에따른제품군구분

10 NoSQL 관련직무동향 참조자료 : indeed.com

11 MongoDB Job 동향 * 2012 년 6 월 indeed.com 통계

12 NoSQL 제품별평가결과 평가기준 Tokyo*Cabinet * Tokyo Tyrant Berkerly DB Memcache DB Voldemort BDB JE REDIS MongoDB Write (Small Data Set) Write (Large Data Set) Random Read (Small Data Set) Random Read (Large Data Set) Speed 일관성 Storage 효율성 Horizontal 확장성 Manageability ( 관리성 ) Stability ( 안정성 ) Community Support * 2011 년 PerfectMarket 자료참조

13 2 Data Modeling & 설계 Pattern

14 MongoDB 주요특징 1) Humongos 라는회사의제품명이었으며현재 10gen 으로 회사명이변경되었다. 2) JSON Type 의데이터저장구조를제공한다. { ename : 주종면 } 3) CRUD(Create, Read, Update, Delete) 위주의다중트랜잭션처리도가능하며인덱스를빠른데이터검색이가능하다. 4) MapReduce( 분산 / 병렬처리 ) 기능을제공한다. 5) Sharding( 분산 )/Replica( 복제 ) 기능을제공한다. 6) Memory Mapping 기술을기반으로 Big Data 처리에탁월한성능을제공한다.

15 Collection 생성 > db.createcollection ( emp, { capped : false, size:8192 }); { "ok" : 1 } capped : 해당공간이모두사용되면다시처음부터 size 재사용할수있는데이터구조를생성할때 : 해당 Collection의최초생성크기지정가능 > db.emp.validate() Collection 의현재상태및정보분석 { "ns" : "test.emp", "firstextent" : "0:61000 ns:test.emp", "lastextent" : "0:61000 ns:test.emp", "extentcount" : 1, "datasize" : 0, "nrecords" : 0, "lastextentsize" : 8192,

16 논리적구조 Database Collection Extent Data Record Emp Collection Data Record Data Record Data Record Data Record Data Record Data Record Length xnext xprev Document { _id: 1,. } Length xnext xprev Document { _id: 2,. } Length xnext xprev Document { _id: 3,. } Length xnext xprev Document { _id: 4,. } Length xnext xprev Document { _id: 5,. } Length xnext xprev Document { _id: 6,. } (Ex) db.createcollection ( emp", {capped:false, size:100000});

17 MongoDB 설계주요특징 1) MongoDB는데이터의중복을허용하며비정형화된설계를지향한다. 2) MongoDB는중첩데이터구조를설계할수있기때문에불필요한 JOIN을최소화시킬수있다. 3) MongoDB는 N:M 관계구조를설계할수있고구축할수있다. 4) MongoDB는 Schema 중심으로설계하지않는다.

18 OODBMS & RDBMS 주문 주문항목 주문 주문항목 강한관계 (Strong Association) 부서 사원 부서 사원 약한관계 (Weak Association) Object Oriented Database 관계 (Relationship) Relationship Database

19 주문전표 주문번호 고객명 담당사원 Magee Womansport 주문날짜 선적날짜 선적여부 주문총금액 601,100 지불방법현금 30 일이내 Y 항목번호 제품명 단가 주문수량 금액 1 Bunny Boot ,500 2 Pro Ski Boot ,000 3 Bunny Ski Pole ,000 4 Pro Ski Pole ,400 5 Himalaya Bicycle ,200 6 New Air Pump ,000 7 Prostar 10Pd.Weight ,000 SUMMIT2

20 RDBMS SQL Insert into s_ord ( ord_id, customer_no, emp_name, total, payment_type, order_filled) Values ( , "Wonman & Sports", 주문테이블정보 "Magee", , Credit, Y ); 주문상세테이블정보 Insert into s_ord_item ( ord_id, item_id, product_name, price) Values ( , 1, Bunny Boots, 135, 500, ); Insert into s_ord_item ( ord_id, item_id, product_name, price) Values ( , 2, Pro Ski Boots, 380, 400, );

21 RDBMS 논리적구조 주문 Table Extent Block(Page) , Wonman & Sports, Magee,601100, Credit,Y , Man & Sports, Magee,34200, Credit,N , Adidas, Magee,23100, Credit,Y , Soleman, Magee,43100, Credit,N... 주문상세 , 1,Bunny Boots, 135, 500, , 2,Pro Ski Boots, 380,400,

22 ORDBMS (Nested Table) 주문테이블 , Bunny Boots, 135, 500, , Pro Ski Boots, 380,400, ,. 4, , 1 Create type product_detail as object (item_no number(2), p_name varchar(50), s_price number(8), qty number(5), amount number(10)); Create type order_detail As Table of product_detail; 2 2, 3, 4, 5, 3 Create table order (order_no char(12), ename varchar2(10),. order_content order_detail) Nested Table order_content;

23 ORDBMS (Varray) 주문테이블 , Bunny Boots, 135, 500, , Pro Ski Boots, 380,400, ,. 4, , 1 Create type product_detail as object (item_no number(2), p_name varchar(50), s_price number(8), qty number(5), amount number(10)); 2 Create type order_detail As varray(90) of product_detail; 2, 3, 4, 5, 3 Create table order (order_no char(12), ename varchar2(10),. order_content order_detail) VARRAY order_content;

24 Embedded Document db.ord.insert( { ord_id : " ", 주문공통정보 customer_name : "Wonman & Sports", emp_name : "Magee", total : "601100", payment_type : "Credit", order_filled : "Y", item_id : [ { item_id : "1", product_name : "Bunny Boots", item_price : "135", 주문상세정보 qty : "500", price : "67000 }, { item_id : "2", product_name : "Pro Ski Boots", item_price : "380", qty : "400", price : " } ] } )

25 Extend Document db.ord.insert( { ord_id : " ", customer_name : "Wonman & Sports", emp_name : "Magee", total : "601100", payment_type : "Credit", order_filled : "Y" }); 주문공통정보 db.ord.update( { ord_id : " "}, { $set : { item_id : [ { item_no : "1", product_name : "Bunny Boots", item_price : "135", qty : "500", price : "67000" }, { item_no : "2", product_name : "Pro Ski Boots", item_price : "380", qty : "400", price : "152000" } ] } } ); 주문상세정보

26 MongoDB 데이터저장구조 (Embedded) Length xnext xprev 주문 / 주문상세 Collection {({ Data Record Document ord_id : ", customer_name : "Wonman & Sports", emp_name : "Magee", total : , payment_type : Credit, order_filled : Y, item_id : [ { item_id : 1, product_name : Bunny Boots, item_price : 135 qty : 500, price : }, { item_id : 2, product_name : Pro Ski Boots, item_price : 380, qty : 400, price : } ] }} * 장점 1) Query 가단순해지고 JOIN 문을실행할필요가없기때문에 Document 단위의데이터저장에효과적이며빠른성능이보장된다. 2) 데이터보안에효과적이다. * 단점 1) Embedded 되는 Document 의크기는최대 16MB 범위에서가능하다. 2) Embedded 되는 Document 가존재하지않는 Collection 에는적합하지않다.

27 Manual Linking > db.ord.insert( { ord_id : " ", customer_name : "Wonman & Sports", emp_name : "Magee", total : "601100", payment_type : "Credit", order_filled : Y } ) 주문공통정보 > o = db.ord.findone( { "ord_id" : " " } ) { "_id" : ObjectId("4fc21223e6cd4d2aadb38622"),. > db.ord_detail.insert( { ord_id : " ", item_id : [ { item_id : "1", product_name : "Bunny Boots", item_price : "135", qty : "500", price : }, { item_id : "2", product_name : "Pro Ski Boots", 주문상세정보 > db.ord_detail.findone({ordid_id : o._id}) item_price : "380", qty : "400", price : " } ], ordid_id : ObjectId("4fc21223e6cd4d2aadb38622 ) } )

28 DBRef 함수 > x = { ord_id : " ", customer_name : "Wonman & Sports", emp_name : "Magee", total : "601100", payment_type : "Credit", order_filled : "Y" } 주문공통정보 db.ord.save(x) > db.ord.find({"ord_id" : " "}) { "_id" : ObjectId("4fc30d0efab534f9e "), > db.ord_detail.save({ ord_id : " ", item_id : [ { item_id : "1", product_name : "Bunny Boots", item_price : "135", qty : "500", price : "67000" }, { item_id : "2", product_name : "Pro Ski Boots", 주문상세정보 item_price : "380", qty : "400", price : "152000" } ], ordid_id : [ new DBRef ("ord", x._id) ] } )

29 MongoDB 데이터저장구조 (Linking) 주문 Collection 주문상세 Collection Data Record Data Record Document Document Length xnext xprev {( ObjectId("4fc21223e6cd4d2aadb38622") ord_id : , customer_name : "Wonman & Sports", emp_name : "Magee", total : , payment_type : Credit, order_filled : Y }} Length xnext xprev {({ ObjectId("4fc21417e6cd4d2aadb38624") ord_id : , item_id : [ { tem_id : 1, product_name : Bunny Boots, item_price : 135, qty : 500, price : }, { item_id : 2, product_name : Pro Ski Boots, item_price : 380 qty : 400, price : }, ObjectId("4fc21223e6cd4d2aadb38622") }} * 장점 * 단점 1) 별도의논리적구조로저장되기때문에 Docum ent 크기에제한받지않는다. 2) 비니지스룰상별도로처리되는데이터구조에적합하다. 1) 매번논리적구조간에 Linking 해야하기때문에 Embedded 보다성능이늦다. 2) Collection 개수가증가하며관리비용이많이든다.

30 계층형데이터구조 KING Empno=7839 Empno=7782 CLARK JONES BLAKE MILLER SCOTT FORD ALLEN WARD MARTIN TURNER JAMES Empno=7934 ADAMS SMITH

31 Self Reference Join (RDBMS) Empno ename mgr KING 7698 BLAKE CLARK JONES MARTIN FORD ADAMS MILLER 7782 b.ename KING KING KING BLAKE. JONES. JIMMY CLARK SELECT a.empno, a.ename, a.mgr, b.ename FROM emp a, emp b WHERE a.mgr = b.empno

32 Ancestor Reference (MongoDB) > db.emp.insert({ "_id" : "7839", "name" : "KING", "job" : "PRESIDENT" }) > db.emp.insert({ "_id" : "7782", "name" : "CLARK", "job" : "ANALYSIST", "PARENT" : "7839" } ) > db.emp.insert({ "_id" : "7934", "name" : "MILLER", "job" : "CLERK", "ANCESTORS" : 7839, "PARENT" : "7782" } ) > db.emp.find({"ancestors" : "7839"}) { "_id" : "7934", "name" : "MILLER", "job" : "CLERK", "ANCESTORS" : [ "7939", "7782" ], "PARENT" : "7782" } > db.emp.find({"parent" : 7839"}) { "_id" : "7782", "name" : "CLARK", "job" : "ANALYSIST", "PARENT" : "7839" }

33 Inheritence (OODBMS) Engine Frame Tire CAR 상속 (Inheritance) Engine Frame Tire Auto-Door BUS TAXI Engine Frame Tire Lamp Gas_Tank CREATE TYPE car AS OBJECT (engine NUMBER(9) Primary Key, frame VARCHAR(30), tire VARCHAR(30)) NOT FINAL; CREATE TYPE bus UNDER car_typ (auto_door VARCHAR(30) FINAL; CREATE TYPE taxi UNDER car_typ (lamp VARCHAR(30), gas_tank VARCHAR(30) FINAL;

34 Inheritence (RDBMS) CAR Engine Frame Tire Car_Type BUS Auto_door TAXI Lamp Gas_tank CREATE TABLE car (engine INTEGER(9) NOT NULL, frame CHAR VARYING(30) NOT NULL, tire CHAR VARYING(30) NOT NULL, car_type CHAR VARYING(4) CHECK IN( BUS, TAXI ), auto_door INTEGER(2), lamp CHAR VARYING(30), gas_tank CHAR VARYING(30) Constraint bus_pk PRIMARY KEY (engine, frame, tire); Engine Frame Tire Car_Type Auto_Door Lamp Gas_Tank A AX_1 R16 TAXI 1 1 B AK_3 R18 BUS 2 A AX_2 R18 TAXI 2 2

35 Inheritence (MongoDB) > db.createcollection ( car ); > db.car.insert({ engine : A, frame : AX_1, tire : R16, car_type : TAXI, lamp : 1, gas_tank : 1 }); > db.car.insert({ engine : B, frame : AK_3, tire : R18, car_type : BUS, auto_door: 2 }); > db.car.insert({ engine : A, frame : AX_2, tire : R18, car_type : TAXI, lamp : 2, gas_tank : 2 }); > db.employees.find(); {"_id" : ObjectId("4f00574f81a153d d2"), engine" : A, "ename" : AX_1, tire : R16, car_type : TAXI, lamp : 1, gas_tank : 1 }); } Engine: A Frame: AX_1 Tire: R16 Car_type: TAXI Lamp: 1 Gas_tank: 1 Engine: B Frame: AK_3 Tire: R18 Car_type: BUS Auto_door: 1 Engine: A Frame: AX_1 Tire: R18 Car_type: TAXI Lamp: 2 Gas_tank: 2

36 N:M 관계 (RDBMS) 제품 카테고리 ASUS EP121 Note Book Samsung eslate 7 Slate PC ipad 3 Tablet

37 N:M 관계 (MongoDB) db.category.insert({"cname" : "Note Book", "pname1" : "Asus EP121 M50" } ); db.category.insert({"cname" : "Tablet", "pname1" : "Asus EP121 M50", "pname2" : "ipad3"} ); db.category.insert({"cname" : "SlatePC", "pname1" : "Asus EP121 M50", "pname2" : "Samsung Slate 7" }); db.product.insert({ "pname" : "Asus EP121 M50", "cname1" : "Note Book", "cname2" : "Tablet", "cname3" : "SlatePC" } ); db.product.insert({ "pname" : "Samsung Slate 7", "cname1" : "SlatePC" } ); db.product.insert({ "pname" : "ipad3", "cname1" : "Tablet" } );

38 3 MongoDB 성능튜닝솔루션

39 성능튜닝솔루션 1) 적절한분석을통해최적의컬렉션구조를설계하라. (Rich Document, Linking, Extent 크기등 ) 2) 빅데이터의빠른검색을위해인덱스를적절히활용하라. ( Hint 함수와 Explain 함수를이용한실행계획적용 ) 3) MongoDB의 Map/Reduce 또는 Aggregation 기능을적절히활용하고 Hadoop과연동을통한 Map/Reduce도고려하라. 4) MongoDB의대표적분산처리솔루션인 Sharding 시스템의적용을충분히고려하라 5) MongoDB는메모리매핑을이용한데이터처리기술을사용하기때문에충분한메모리영역을확보하라.

40 INDEX 종류 Non-Unique/Unique Index Background Index Covered Index DropDups Index Sparse Index TTL Index GeoSpatial Index

41 Database Profiler 1) Profiler 환경설정 > db.setprofilinglevel(2); {"was" : 0, "slowms" : 100, "ok" : 1} "was" 는이전설정정보 > db.getprofilinglevel() 현재설정되어있는정보 2 0 : Off, 1 : default > 100 ms 2 : System 에서발생한모든정보 2) Profiler 환경분석결과및상태확인 > db.system.profile.find( { millis : { $gt : 5 } } ) 실행시간이 5 초이상소요된문장검색

42 3) Hint 절과실행계획 > db.emp.find({eno : 1101}).hint({eno:1}).explain(); { "cursor" : "BtreeCursor eno_1", Index Scan "nscanned" : 1, 검색조건을만족하는항목수 "nscannedobjects" : 1, 검색대상이된 Collection 수 "n" : 1, 조건을만족하는 Document 수 "millis" : 0, 조건을검색하는데소요된시간 "nyields" : 0, Read Lock이발생했던횟수 "nchunkskips" : 0, Shard에서 Chunk Migration된 Doc. 수 "ismultikey" : false, 다중 key 인덱스가사용되면 True "indexonly" : false, Index 만사용하여 Query했으면 True "indexbounds" : { "eno" : [ [ 1101, 1101 ] ] } } > db.emp.find().hint({$natural:1}).explain(); { "cursor" : "BasicCursor", Full Collection Scan "nscanned" : 3, "nscannedobjects" : 3, "millis" : 0, "indexonly" : false, "indexbounds" : { } }

43 > db.employees.find ({ deptno : 10, ename : "CLARK" }).explain() { "cursor" : "BtreeCursor deptno_1_ename_1", "nscanned" : 1, "nscannedobjects" : 1, "n" : 1, "millis" : 0, "nyields" : 0, "nchunkskips" : 0, "ismultikey" : false, "indexonly" : true, "indexbounds" : { "deptno" : [ [ 10, 10 ] ], "ename" : [ [ "CLARK", "CLARK" ] ] } } Covered 인덱스만으로조건검색

44 > db.employees.ensureindex({ comm : 1 }, { sparse : true }) > db.employees.find().sort({comm : -1}) { "_id" : ObjectId("5019dd5b2bffb7e0a9073be7"), "empno" : 7654, "deptno" : 30 } { "_id" : ObjectId("5019dd5b2bffb7e0a9073be5"), "empno" : 7521, deptno" : 30 } { "_id" : ObjectId("5019dd5b2bffb7e0a9073be4"), "empno" : 7499, "deptno" : 30 } > db.employees.dropindex({ comm : 1 }) > db.employees.find().sort({comm : -1}) SPARSE 인덱스삭제후전체검색을수행하면모든 Document 들이출력된다. {"_id":objectid("5019dd5b2bffb7e0a9073be7"),"empno" : 7654,, "deptno" : 30 } {"_id":objectid("5019dd5b2bffb7e0a9073be5"), "empno" : 7521, "deptno" : 30 }.. {"_id":objectid("5019dd5c2bffb7e0a9073bef"), "empno" : 7902,, "deptno" : 10 }

45 빅데이터추출및분석 1) MongoDB의 Map/Reduce 기능을이용한빅데이터의추출 2) MongoDB의 Aggregation Framework을이용한빅데이터의추출 3) MongoDB와 Hadoop의 Map-Reduce를연동한빅데이터의추출

46 1) MongoDB Map/Reduce 기능을이용 Map() Group() emit() MongoDB sort() Finalize() Reduce(k, v)

47 Oracle & Mongo Query 비교 SELECT deptno, job, SUM(sal) AS msum, <- 부서별급여합계 COUNT(*) AS recs, <- 부서별인원수 AVG(sal) AS mavg, <- 평균급여금액 MIN(sal) AS mmin, <- 최소급여액 MAX(CASE <- 최대급여액 WHEN sal > 1000 THEN sal END) AS mmax FROM emp WHERE (hiredate > ' AND hiredate < ') AND sal > 800 GROUP BY deptno, job HAVING min(sal) > 0 ORDER BY recs DESC 대상 Table 과 Collection 검색조건 검색 Column 또는 Field Aggregate 또는 Procedure Logic Aggregate 또는 Procedure Logic Aggregate Filter 또는 Sorting db.runcommand ({ mapreduce: "emp", query: { hiredate : { $gt : ' ', $lt : ' ' }, sal : { $gt : 800 } }, map: function() { emit( { d1 : this.deptno, d2 : this.job }, { msum: this.sal, recs: 1, mmin: this.sal, mmax: this.sal > 1000 } ); }, reduce: function(key, vals) { var ret = { msum:0, recs:0, mmin:0, mmax:0 }; for (var i=0 ; i < vals.length; i++) { ret.msum += vals[i].msum; ret.recs += vals[i].recs; if (vals[i].mmin < ret.mmin) ret.mmin=vals[i].mmin; if (vals[i].mmax > 1000) ret.mmax=vals[i].mmax; } return ret; }, finalize: function(key, val) { val.mavg=val.msum/val.recs; return val; }, out: "result1", verbose: true }); db.result1.find( { "value.mmin : { $gt:0}}).sort({ "value.recs : 1});

48 2) Aggregation Framework을이용한데이터처리 - Aggregation을위해 MongoDB의 Map/Reduce를반드시사용해야한다. - Aggregation Framework는데이터추출에최적화되어만들어진기능이다. - 실시간 Aggregation은 SQL의 Group By절과유사하다. - MongoDB Map/Reduce는 JavaScript로생성되어있다. - JavaScript는외부데이터처리에제한적이다.

49 (1) Aggregation Framework

50 3) MongoDB 와 Hadoop 을연동한데이터처리 MongoDB Input Split Data Split Data Split Data Split Data Map(k,v,ctx) combine(k,v) Partitioner(k) sort(keys) MongoDB Reduce(k, v)

51 (1) Map Function in Python

52 (2) Reduce Function in Python

53 (3) Run in Hadoop Map/Reduce

54 (4) Map/Reduce 결과

55 Sharding System Shard Server Config Server Mongod Mongod Mongod Mongod Route Server (MongoS) Mongo.exe Mongo.exe

56 MongoDB Architecture Resident Area (Working Set) Mapped Cache Area Virtual Memory Area Virtual Area * 최초약 440 MB Journal Area 38 MB ( 최초 22MB) 80 MB 160MB 160 MB Client Process (Mongo.exe) Mapped(Data) file Server Process (Mongod.exe) 60 s 마다동기화 100 ms 마다 100 mb 저장 Journal file SALES. NS (16MB) SALES.0 (64MB) Prealloc.0 (1GB) Prealloc.1 (1GB) Prealloc.2 (1GB)

57 MongoDB 관련 OX 퀴즈 질문정답 MongoDB는기존의관계형데이터베이스를완전히대체할수있다. MongoDB는사용자에의해 COMMIT과 ROLLBACK 할수있다 MongoDB는비정형 DB이기때문에설계가요구되지않는다. MongoDB는 CPU보다고사양의메모리가요구된다. MongoDB의 Map/Reduce를통해충분한성능이보장된다. MongoDB의 Read 성능은 Write 성능보다훨씬빠르다. MongoDB는라이센스가없다. X O X O X X X

58 2013년관련정보 정부교육 관련서적 커뮤니티교육