Java development 2.0: MongoDB: (적절한) RDBMS 이동 기능을 제공하는 NoSQL 데이터 저장소
Java 코드 및 Groovy를 사용하여 문서를 작성하고 쿼리하기 요약: NoSQL 데이터베이스에 대해 알아보면 NoSQL RDBMS라고도 하는 MongoDB를 만날 수 있습니다. 이 기사에서는 MongoDB의 사용자 정의 API, 대화식 쉘 및 RDBMS 스타일 동적 쿼리 지원과 더불어 빠르고 쉬운 MapReduce 계산에 대해서도 살펴봅니다. 그런 다음 MongoDB의 네이티브 Java™ 언어 드라이버와 사용하기 쉬운 Groovy 랩퍼인 GMongo를 사용하여 데이터를 작성하고, 찾고, 조작하는 방법에 대해 설명합니다.
원문 게재일: 2010 년 9 월 28 일
번역 게재일: 2011 년 2 월 15 일
난이도: 중급
원문: 보기
PDF: A4 and Letter (56KB | 13 pages)Get Adobe® Reader®
페이지뷰: 8446 회
의견: 0 (의견 추가)
번역 게재일: 2011 년 2 월 15 일
난이도: 중급
원문: 보기
PDF: A4 and Letter (56KB | 13 pages)Get Adobe® Reader®
페이지뷰: 8446 회
의견: 0 (의견 추가)
오픈 소스 문서 지향적 데이터베이스 중에서 MongoDB는 RDBMS 기능을 갖춘 NoSQL 데이터베이스라고 언급되기도 한다. 예를 들어, MongoDB에서는 미리 정의된 MapReduce 함수가 없어도 동적 쿼리가 지원된다. 또한 MongoDB에는 손쉽게 데이터 저장소에 액세스하는 기능을 제공하는 대화식 쉘이 있으며 기본적으로 지원되는 샤드(shard) 기능을 사용하면 여러 노드로 확장할 수 있다.
MongoDB의 API는 JSON 오브젝트와 JavaScript 함수의 혼합체이다. 개발자는 명령행 인수를 사용할 수 있는 쉘 프로그램이나 언어 드라이버를 통해 MongoDB와 상호 작용하여 데이터 저장소 인스턴스에 액세스할 수 있다. 그렇지만 JDBC와 같은 드라이버는 없다. 이는
ResultSet
또는 PreparedStatement
를 다루지 않아도 된다는 의미이다. MongoDB는 빠르다는 장점도 가지고 있다. 이는 주로 데이터를 쓰는 방법 즉, 데이터를 메모리에 저장한 후 나중에 백그라운드 스레드를 통해 디스크에 기록하는 방법이 속도 향상 효과를 제공하기 때문이다.
MongoDB에 대해 설명하는 이 기사는 CouchDB에 대해 소개하는 필자의 기사(참고자료 참조)를 바탕으로 하며 다시 한번 주차 티켓 예제를 사용하여 스키마리스 데이터 저장소의 유연성을 보여 준다. MongoDB의 API 및 동적 쿼리 지원이 MongoDB의 두 가지 주요 차별 요소이므로 이러한 차별 요소에 중점을 두고 MongoDB의 쉘 및 Java 언어 드라이버의 사용법을 보여 주는 예제를 살펴본다. 기사 후반부에서는 MongoDB의 MapReduce 구현에서 제공하는 일부 정보를 사용하는 Groovy 랩퍼인 GMongo에 대해서도 소개한다. 이 기능도 이 특별한 NoSQL 옵션의 주요 특징 중 하나이다.
스키마리스로 이동해야 하는 이유
스키마리스 저장소가 모든 분야에 적합한 것은 아니기 때문에 문서 지향적 방법과 관계형 방법의 선택 기준을 이해해야 한다. 데이터를 다양한 양식으로 참조할 수 있지만 기본 모델이 동일한 분야에서는 문서의 유연성이 중요하다. 명함이 전형적인 예이다. 수많은 명함을 보면 다양한 데이터가 있다는 것을 알 수 있다. 일부 명함에는 팩스 번호나 회사 URL이 적혀 있기도 하지만 우편 주소, 두 개의 전화번호 또는 Twitter 핸들이 적혀 있는 명함도 있다. 데이터는 다양하지만 모델이나 기능은 동일하다. 즉, 명함에는 연락처 정보가 있다.
명함을 관계형 용어로 모델링할 수는 있지만 꽤 복잡하다. 관계형 데이터베이스를 보면 예를 들어, 팩스 번호를 사용하는 하나 또는 두 개의 레코드마다 팩스 열의 값이 널값인 레코드를 많이 볼 수 있다. 또한 관계형 시스템에서는 열 유형을 지정해야 하기 때문에 주소 필드 길이 등으로 인한 제약이 발생할 수 있다. (아마도 Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch에 사는 사람의 주소를 저장해야 하는 경우를 생각해 본 적이 없을 것이다. 하지만 이 마을이 실제로 존재한다.)
문서 지향적 데이터 저장소로 명함을 모델링하는 작업은 매우 쉽다. 스키마를 사용하지 않는다는 것은 길이에 상관 없이 필요한 모든 데이터를 문서에 담을 수 있다는 것을 의미한다. 명함의 특성을 고려하면 다양한 특성을 지닌 문서로 모델링하는 것이 적합하다.
스키마리스 데이터 저장소는 대부분 ACID(Atomicity, Consistency, Isolation, and Durability)를 완벽하게 지원하지는 않기 때문에 안정성 및 일관성이 중요한 분야에서는 문제가 발생할 수 있다. NoSQL 방법의 지지자는 확장하기 위해 다중 노드를 도입하는 순간부터 불가피하게 발생하는 중단 시간을 고려하지 않는 경우에만 ACID가 작동한다고 주장한다. 핵심은 스키마리스 데이터 저장소가 관계형 데이터 저장소보다 쉽게 확장할 수 있으므로 문서 지향적 저장소가 웹 기반 애플리케이션에 적합하다는 것이다.
MongoDB 시작하기
MongoDB는 대상 운영 체제별 다운로드를 제공하므로 매우 쉽게 시작할 수 있다. 예를 들어, MongoDB를 Mac OS X에 설정할 경우 해당 2진 파일을 다운로드한 후 압축을 풀고 데이터 디렉토리(MongoDB가 데이터 저장소의 내용을 쓰는 디렉토리)를 작성한 다음
mongodb
명령을 사용하여 인스턴스를 시작하기만 하면 된다. (물론 데이터를 쓸 위치를 프로세스에 알려줘야 한다.)목록 1에서는 MongoDB를 시작하면서
data/db
디렉토리에 데이터를 저장하도록 지정하고 있다. 그리고 verbose
플래그도 지정한다. v가 많을수록 더 많은 세부사항이 표시된다. 목록 1. Mac OS X용 MongoDB
iterm$ ./bin/mongod — dbpath ./data/db/ ——vvvvvvvv |
MongoDB를 시작한 후에는 대화식 쉘 작업을 바로 시작할 수 있다.
mongo
명령을 실행하면 목록 2와 같은 내용이 표시된다. 목록 2. MongoDB 쉘 시작하기
iterm$ ./bin/mongo MongoDB shell version: 1.6.0 connecting to: test > |
쉘을 시작하면 초기에 "test" 데이터 저장소에 연결된다는 것을 알 수 있다. 여기에서는 이 데이터 저장소를 사용하여 문서를 작성하고 찾는 방법을 설명할 것이다. 이 작업에는 일부 JavaScript 및 JSON을 작성하는 작업도 포함되어 있다.
문서 작성 및 찾기
CouchDB와 마찬가지로 MongoDB에서도 JSON을 사용하여 문서를 작성한다. (이러한 문서는 효율성을 위해 JSON의 2진 양식인 BSON으로 저장된다.) 대화식 쉘에서 주차 티켓을 작성하기 위해 목록 3과 같은 JSON 문서를 작성할 수 있다.
목록 3. 간단한 JSON 문서
> ticket = { officer: "Kristen Ree" , location: "Walmart parking lot", vehicle_plate: "Virginia 5566", offense: "Parked in no parking zone", date: "2010/08/15"} |
Enter 키를 누르면 목록 4와 같이 형식화된 JSON 문서가 표시된다.
목록 4. MongoDB의 응답
{ "officer" : "Kristen Ree", "location" : "Walmart parking lot", "vehicle_plate" : "Virginia 5566", "offense" : "Parked in no parking zone", "date" : "2010/08/15" } |
방금 전 주차 티켓의 JSON 표현을 작성했으며 그 이름은 "ticket"이다. 이 문서를 지속적으로 유지하려면 관계형 용어의 스키마와 유사한 콜렉션에 연관시켜야 한다. 목록 5에서는 ticket을
tickets
콜렉션에 연관시킨다. 목록 5. ticket 인스턴스 저장하기
> db.tickets.save(ticket) |
MongoDB에서는
tickets
콜렉션을 미리 작성하지 않아도 된다. 콜렉션은 처음 참조될 때 작성된다. 이제 위와 같은 방법으로 티켓을 몇 개 더 작성한다. 다음 섹션에서는 이러한 티켓을 찾아볼 것이므로 좀 더 흥미로울 것이다.
문서 찾기
콜렉션에 있는 모든 문서를 찾는 작업은
find
명령만 호출하면 되기 때문에 쉽다(목록 6 참조). 목록 6. MongoDB의 모든 문서 찾기
> db.tickets.find() { "_id" : ObjectId("4c7aca17dfb1ab5b3c1bdee8"), "officer" : "Kristen Ree", "location" : "Walmart parking lot", "vehicle_plate" : "Virginia 5566", "offense" : "Parked in no parking zone", "date" : "2010/08/15" } { "_id" : ObjectId("4c7aca1ddfb1ab5b3c1bdee9"), "officer" : "Kristen Ree", "location" : "199 Baldwin Dr", "vehicle_plate" : "Maryland 7777", "offense" : "Parked in no parking zone", "date" : "2010/08/29" } |
매개변수 없이
find
명령을 실행하면 특정 콜렉션의 모든 문서가 리턴된다. 이 경우에는 tickets
콜렉션의 문서가 리턴된다. 목록 6을 보면 MongoDB가 각 문서의 ID를 작성했다는 것을 알 수 있다. 이러한 ID에는
_id
키가 지정되어 있다. JSON 문서의 개별 키를 검색할 수 있다. 예를 들어, Walmart 주차장에서 발행한 모든 티켓을 찾으려는 경우 목록 7의 쿼리를 사용할 수 있다.
목록 7. 쿼리로 찾기
> db.tickets.find({location:"Walmart parking lot"}) |
JSON 문서의 사용 가능한 키를 검색할 수 있다(이 경우에는
offense, _id
, date
등). 그리고 정규식을 사용하여 키 값(예: location
)을 검색할 수도 있다(목록 8 참조). 이 정규식은 SQL의 LIKE
명령문과 매우 비슷하게 작동한다. 목록 8. 정규식으로 찾기
> db.tickets.find({location:/walmart/i}) |
정규식 명령문(이 경우에는 walmart) 뒤에 오는
i
는 해당 명령문에서 대소문자를 구분하지 않는다는 것을 의미한다. MongoDB의 Java 드라이버
MongoDB의 Java 언어 드라이버가 이전 섹션에 살펴본 대부분의 JSON 및 JavaScript 코드를 추상화하는 기능을 제공하므로 사용자는 Java API를 직접 사용하면 된다. MongoDB의 Java 드라이버를 시작하려면 해당 드라이버를 다운로드한 후 결과 .jar 파일을 클래스 경로에 추가한다(참고자료 참조).
이제
tickets
콜렉션에 다른 티켓을 작성해 보자. 이 콜렉션은 test
데이터 저장소에 저장되어 있다. Java 드라이버를 사용할 경우에는 먼저 MongoDB 인스턴스에 연결한 다음 test
데이터베이스와 tickets
콜렉션을 가져온다(목록 9 참조). 목록 9. MongoDB의 Java 드라이버 사용하기
Mongo m = new Mongo(); DB db = m.getDB("test"); DBCollection coll = db.getCollection("tickets"); |
Java 드라이버를 사용하여 JSON 문서를 작성하려면
BasicObject
를 작성한 후 이 오브젝트에 이름과 값을 연관시킨다(목록 10 참조). 목록 10. Java 드라이버로 문서 작성하기
BasicDBObject doc = new BasicDBObject(); doc.put("officer", "Andrew Smith"); doc.put("location", "Target Shopping Center parking lot"); doc.put("vehicle_plate", "Virginia 2345"); doc.put("offense", "Double parked"); doc.put("date", "2010/08/13"); coll.insert(doc); |
Java 드라이버를 사용하면 매우 쉽게 문서를 찾고 결과 커서를 반복할 수 있다(목록 11 참조).
목록 11. Java 드라이버로 문서 찾기
DBCursor cur = coll.find(); while (cur.hasNext()) { System.out.println(cur.next()); } |
Java 개발자는 Java 드라이버를 기반으로 빌드된 Groovy의 멋진 추상화를 포함한 몇 가지 MongoDB 라이브러리를 사용할 수 있다. 다음 섹션에서는 애플리케이션을 빌드하는 과정을 통해 기본 Java 드라이버와 조금 더 많은 기능을 제공하는 Groovy 드라이버를 살펴본다. 이 멋진 애플리케이션에서는 MongoDB의 MapReduce 함수도 볼 수 있다. 이 기사에서는 이 기능을 사용하여 문서 콜렉션을 처리한다.
MongoDB를 이용한 Twitter 분석
데이터베이스에 저장되어 있기만 한 데이터는 별로 의미가 없다. 그러한 데이터를 효율적으로 활용할 수 있어야 한다. 이 기사에서는 이 애플리케이션을 사용하여 먼저 Twitter의 일부 정보를 캡처하여 MongoDB에 저장할 것이다. 그런 다음 필자를 가장 많이 리트위트한 사용자와 필자의 트위트 중 가장 많이 리트위트된 트위트를 계산할 것이다.
이 애플리케이션을 실행하려면 먼저 Twitter와 통신하여 데이터를 캡처할 수 있는 방법이 필요하다. 이를 위해 Twitter의 일부 RESTful API를 간단한 Java API로 추상화한 Twitter4J라는 멋진 라이브러리를 사용한다(참고자료 참조). 여기에서는 이 API를 사용하여 필자의 리트위트를 찾는다. 데이터를 찾은 후에는 데이터에 목록 12와 같은 JSON 문서 형식을 지정한다.
목록 12. JSON을 통해 저장된 리트위트
{ "user_name" : "twitter user", "tweet" : "Podcast ...", "tweet_id" : 9090...., "date" : "08/12/2010" } |
목록 13에서는 MongoDB의 네이티브 Java 드라이버와 Twitter4J를 간단한 드라이버 애플리케이션(이 또한 Java 코드로 작성됨)에서 함께 사용하여 데이터를 캡처하고 MongoDB에 저장한다.
목록 13. MongoDB에 Twitter 데이터 삽입하기
Mongo m = new Mongo(); DB db = m.getDB("twitter_stats"); DBCollection coll = db.getCollection("retweets"); Twitter twitter = new TwitterFactory().getInstance("<some user name>", "<some password>"); List<Status> statuses = twitter.getRetweetsOfMe(); for (Status status : statuses) { ResponseList<User> users = twitter.getRetweetedBy(status.getId()); for (User user : users) { BasicDBObject doc = new BasicDBObject(); doc.put("user_name", user.getScreenName()); doc.put("tweet", status.getText()); doc.put("tweet_id", status.getId()); doc.put("date", status.getCreatedAt()); coll.insert(doc); } } |
목록 13의 "
twitter_stats
" 데이터베이스는 드라이버 실행 전에 없었기 때문에 요청이 발생할 때 작성되었다. 이는 "retweets
" 콜렉션에도 동일하게 적용된다. 데이터베이스와 콜렉션이 작성되면 Twitter4J의 Twitter
오브젝트가 생성된 후 최근 20개의 리트위트가 리턴된다. 이제 Twitter4J에서 리턴한
Status
오브젝트의 List
에는 필자의 리트위트가 있다. 각 항목에 대해 관련 데이터를 쿼리한 후 MongoDB의 BasicDBObject
인스턴스가 작성되고 관련 데이터가 이 인스턴스에 채워진다. 마지막으로 각 문서가 저장된다. MongoDB의 MapReduce
모든 데이터를 저장했으므로 이제 데이터를 조작할 차례이다. 원하는 정보를 가져오려면 두 가지 일괄처리 조작을 수행해야 한다. 먼저 각 Twitter 사용자가 나열된 횟수의 합계를 구한다. 그런 다음 각
tweet
(또는 tweet_id
)가 팝업된 횟수의 합계를 구한다. MongoDB에서는 MapReduce를 사용하여 일괄처리 데이터 조작을 수행한다. 크게 보았을 때 MapReduce 알고리즘은 문제를 두 단계로 나눠서 접근한다. 먼저 Map 함수는 대량 입력을 받아서 작은 단위로 분할한 다음 다른 프로세스에게 전달하도록 설계되었다. 그리고 분할된 데이터를 받은 프로세스에서 데이터에 대한 조작을 수행한다. Reduce 함수는 Map의 개별 응답을 하나의 최종 출력으로 작성하는 역할을 담당한다.
MongoDB의 핵심 API가 JavaScript이기 때문에 MapReduce 함수도 JavaScript로 작성되었다. Java 드라이버를 사용하기는 해도 JavaScript로 MapReduce 함수를 작성해야 한다. 물론 JavaScript를
String
이나 BasicDBObject와 유사한 오브젝트로 정의할 수 있다. 여기에서는 MongoDB의 기본 드라이버를 기반으로 하는 간단한 랩퍼 라이브러리를 사용하여 작업을 단순화하고 코딩 시간을 절약한다. GMongo라는 이 랩퍼는 Groovy에서 활용할 수 있도록 Groovy로 작성되었다. 그래도 여전히 MapReduce 함수를 JavaScript로 작성해야 하지만 Groovy의 다중 행 문자열 기능을 사용하면 문자열을 이스케이프하지 않아도 되기 때문에 작업이 조금 더 쉬워진다. JavaScript로 작성된 MapReduce 함수
필자를 가장 많이 리트위트한 사용자를 찾으려면 두 가지 작업을 수행해야 한다. 먼저 JSON 문서 구조의
user_name
특성을 키로 사용하는 map
함수를 작성해야 한다. 이 작업은 목록 14와 같이 매우 쉽다. 목록 14. JavaScript로 작성된 간단한 Map 함수
function map() { emit(this.user_name, 1); } |
이
map
함수는 간단하다. 전달된 모든 문서의 user_name
특성을 가져온 다음 emit
를 호출하며, 두 번째 매개변수는 값이다. 이 값은 기본적으로 키의 수이다. 개별 문서의 경우에는 이 값이 1이다. 앞으로 이 값을 사용하여 합계를 구하는 방법을 살펴볼 것이다. 목록 14에서는 필자가 지정한 키(
user_name
특성)와 값을 사용하여 emit
함수를 호출했다. 이 함수의 컨텍스트에서 this
변수는 JSON 문서 자체를 의미한다. 다음으로
reduce
함수를 작성해야 한다(목록 15 참조). 이 함수는 적절하게 그룹화된 모든 문서를 가져와서 값의 합계를 구한다. 목록 15. JavaScript로 작성된 Reduce 함수
function reduce(key, vals) { var sum = 0; for(var i in vals) sum += vals[i]; return sum; } |
목록 15에서 볼 수 있듯이
reduce
에 전달된 key
및 vals
변수는 function reduce("asmith", [1,1,1,1])
;와 같은 형태로 해석되며 물론 이는 user_name
이 asmith
인 사용자가 네 개의 다른 문서에 있다는 것을 의미한다. 즉, A. Smith가 필자를 네 번 리트위트했다는 것이다. vals
변수를 반복하여 리턴된 간단한 sum
을 통해 이를 확인할 수 있다. Groovy로 작성된 MapReduce 함수
다음으로 GMongo를 사용하는 Groovy 스크립트를 작성한 후
map
및 reduce
함수를 적절하게 삽입한다(목록 16 참조). 목록 16. MapReduce를 위한 Groovy 스크립트
mongo = new GMongo() def db = mongo.getDB("twitter_stats") def res = db.retweets.mapReduce( """ function map() { emit(this.user_name, 1); } """, """ function reduce(key, vals) { var sum = 0; for(var i in vals) sum += vals[i]; return sum; } """, "result", [:] ) def cursor = db.result.find().sort(new BasicDBObject("value":-1)) cursor.each{ println "${it._id} has retweeted you ${it.value as int} times" } |
목록 16에서는 먼저
GMongo
의 인스턴스를 작성하고 "twitter_stats
" 데이터 저장소를 가져온다. 이 모든 작업은 기본 Java 드라이버를 사용할 때와 매우 비슷하다. 그런 다음
retweets
콜렉션에 대해 mapReduce
메소드를 호출한다. GMongo 드라이버를 사용하면 목록 13과는 달리 콜렉션을 가져오지 않고 직접 참조할 수 있다. mapReduce
메소드에서는 네 개의 매개변수를 사용한다. 처음 두 개는 JavaScript로 정의된
map
및 reduce
함수를 나타내는 String
이다. 세 번째 매개변수는 MapReduce의 결과를 가지고 있는 오브젝트의 이름이며, 마지막 매개변수는 조작을 완료하는 데 필요한 입력 쿼리이다. 예를 들어, MapReduce 함수에 특정 JSON 문서(예를 들어, 특정 데이터 범위 내의 문서) 또는 그러한 문서 중 일부만 전달할 수 있다. 그런 다음
result
오브젝트(JSON 문서)를 쿼리하고 sort
메소드를 호출한다. 목록 16의 sort
메소드를 호출하려면 {value:-1}
과 같은 JSON 문서가 필요하다. 이는 큰 값이 맨 위에 오는 역순으로 정렬하겠다는 의미이다. 리턴된 cursor
오브젝트는 기본적으로 반복자이다. 따라서 Groovy의 멋진 each
를 이 오브젝트에 직접 사용하여 간단한 보고서를 출력할 수 있다. 이 보고서에서는 필자를 가장 많이 리트위트한 사용자부터 차례대로 보여 준다. 목록 16의 스크립트를 실행하면 목록 17과 같은 출력이 표시된다.
목록 17. MapReduce 출력
bglover has retweeted you 3 times bobama has retweeted you 3 times sjobs has retweeted you 2 times ... |
이제 가장 많이 리트위트한 사용자를 알게 되었다. 하지만 가장 많이 리트위트된 트위트를 보고하려면 어떻게 해야 할까? 이 또한 매우 간단한 작업이다.
user_name
대신 tweet
특성을 키로 사용하는 map
함수를 정의하면 된다(목록 18 참조). 목록 18. 또 하나의 Map 함수
function map() { emit(this.tweet, 1); } |
하나 더 덧붙이자면
reduce
함수는 단순히 그룹화된 키의 합계만 구하는 것이므로 앞에서 사용한 함수를 그대로 사용할 수 있다. 결론
이 기사에서는 MongoDB를 빠르게 살펴보면서 수행할 수 있는 작업의 일부만을 다루었다. 그럼에도 불구하고 이 기사를 통해 높은 유연성을 제공하는 MongoDB의 스키마리스 특성을 이해했기를 바란다. 이 특성은 기사의 앞부분에서 제시했던 명함 예제와 같이 데이터 요소가 다양하면서도 일반적으로 관련되어 있는 분야에 특히 유용한다.
MongoDB와 CouchDB는 둘 다 스키마리스 유연성을 지원하기는 하지만 큰 차이점을 가지고 있다. MongoDB의 기능은 RDBMS와 유사한 형태를 지니고 있기 때문에 RDBMS 관점에서 작업하기도 쉽고 익숙하기도 하다. MongoDB를 사용하면 동적 쿼리를 실행할 수 있고 Java, Ruby, PHP 등의 네이티브 언어로 작업할 수도 있다. 그리고 강력한 MapReduce도 활용할 수 있다.
문서 지향적 데이터베이스가 모든 분야에 적합한 것은 아니다. 금융 데이터를 처리하는 분야와 같이 많은 트랜잭션이 발생하는 분야에서는 아마도 안정적인 ACID가 지원되는 기존 RDBMS가 더 적합할 것이다. 하지만 높은 처리 속도와 유연한 데이터 모델이 필요한 애플리케이션에는 MongoDB가 적합할 것이다.
참고자료
교육
- Java development 2.0: 이 developerWorks 시리즈에서는 스키마리스 데이터 저장소(2010년 5월)와 sharding(2010년 8월)을 소개하는 최신 기사를 포함하여 Java 개발 환경을 다시 정의하고 있는 각종 기술과 도구를 탐구한다.
- "Java development 2.0: CouchDB와 Groovy의 RESTClient를 이용한 REST"(Andrew Glover 저, developerWorks, 2009년 11월): CouchDB를 소개하는 이 기사에서는 관계형 데이터베이스와 문서 지향적 데이터베이스의 차이점에 대해 자세히 설명한다.
- "CouchDB basics for PHP developers"(Thomas Myer 저, developerWorks, 2010년 3월): 숙련된 PHP 개발자를 위해 CouchDB를 기술 도구 상자에 추가하는 방법을 설명한다.
- "MongoDB and CouchDB: vastly different queries"(Andrew Glover 저, The Disco Blog, 2010년 9월): 쿼리를 중심으로 MongoDB와 CouchDB의 차이점을 살펴본다.
- "Resolve common concurrency problems with GPars"(Alex Miller 저, developerWorks, 2010년 9월): Twitter4J 라이브러리에 대한 자세한 설명과 Groovy의 병렬 프로그래밍 라이브러리에 대한 좋은 소개를 볼 수 있다.
- "OAuth-ing Twitter with Twitter4J"(Andrew Glover 저, The Disco Blog, 2010년 9월): Twitter와 Twitter4J에서는 더 이상 기본 권한 부여가 허용되지 않으므로 대신 OAuth를 사용하는 방법을 배워보자.
- Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch: Llanfair PG 또는 Llanfairpwll이라고도 하는 이 마을은 Wales에 있다.
- MongoDB's Java language center: MongoDB를 Java 언어 드라이버 및 연관된 랩퍼와 함께 사용하는 방법을 설명하는 튜토리얼과 링크를 제공한다.
- 이런 기술 주제와 다른 기술 주제에 대한 서적 정보는 Java technology bookstore를 참조한다.
- developerWorks Java 기술 영역: Java 프로그래밍과 관련된 모든 주제를 다루는 여러 편의 기사를 찾아보자.
- MongoDB.org: MongoDB와 Java 언어 드라이버를 다운로드할 수 있다.
- Download GMongo: 기본 Java 언어 드라이버 대신 사용할 수 있는 Groovy 랩퍼이다.
- My developerWorks 커뮤니티에 참여하자. 개발자가 이끌고 있는 블로그, 포럼, 그룹 및 Wiki를 살펴보면서 다른 developerWorks 사용자와 의견을 나눌 수 있다.
Andrew Glover는 개발자이자 저자이며 또한 강사이자 기업가로 동작 지향적 개발 및 연속적인 통합, 신속한 소프트웨어 개발에 대한 열정으로 가득 차 있다. 그의 블로그에서 그에 관한 다양한 정보를 얻을 수 있다.
댓글 없음:
댓글 쓰기