2020.02.18 NoSQL?
참조 url : 조대협 (http://bcho.tistory.com)
Mongo DB는 NoSQL 중에서 가장 널리 사용되는 인기있는 제품이다. 사용과 운영이 다른 시스템에 비해서 매우 쉽고, JSON 기반의 Document를 제공하기 때문에, 데이타 구조에 대한 이해 및 사용이 쉽다. 또한 index나 search와 같은 feature를 제공하고 있고, 근래에는 Text Search와 GridFS를 이용한 파일 저장 그리고, 위치 정보 저장 및 쿼리등 다양한 기능을 제공하고 있다.
Mongo DB는 10gen이라는 회사에서 개발되어서, 현재 오픈소스로와 상용 버전으로 공급되고 있다.
이 글에서는 Mongo DB에 대한 이해를 돕기 위해서 간단한 설치에서 부터, 자바 기반의 프로그래밍 샘플까지 소개하도록 한다.
1.설치
1) 다운로드 하기
mongodb는 http://www.mongodb.org/downloads 에서 다운로드 받을 수 있다. 여기서는 Windows 64-bit Production Release 버전을 기준으로 한다.
zip 파일을 다운로드 받은 후에 C:\dev\mongodb-win32-x86_64-2.4.3 디렉토리에 압축을 풀었다.
2) Mongodb 구동
C:\dev\mongodb-win32-x86_64-2.4.3 에서 다음과 같은 명령어를 이용하여 구동한다.
.\bin\mongod --dbpath C:\dev\mongodb-win32-x86_64-2.4.3\data |
3) 콘솔 확인
구동후에, http://localhost:28017 을 접속하면 아래와 같이 mongodb의 기본 관리 화면을 접속할 수 있다.
2.간단한 테스팅
인스톨이 끝났으면 간단한 테스트를 해보자, ./bin/mongo.exe를 수행하면 Java Script 기반의 쉘이 수행된다. 이해를 돕기 위해서 하나의 테이블에 Insert , select, delete, update를 수행하는 명령을 SQL 문장과 비교해서 소개한다.
Insert
SQL : insert into users ("name","city") values("terry","seoul")
Mongo DB : db.users.insert({_id:"terry",city:"seoul"})
Select
SQL : select * from users where id="terry"
Mongo DB : db.users.find({_id:"terry"})
Update
SQL : update users set city="busan" where _id="terry"
Mongo DB : db.users.update( {_id:"terry"}, {$set :{ city:"Busan" } } )
Delete
SQL : delete from users where _id="terry"
Mongo DB : db.users.remove({_id:"terry"})
간단하게 나마, mongodb query에 대해서 설명하였다.
조금 더 자세한 쿼리에 대한 설명은 http://docs.mongodb.org/manual/crud/ 를 참고하기 바란다.
3. 자바로 간단한 프로그램 작성하기
지금까지 설치와 간단한 쿼리 수행을 해봤다. 그러면 이번에는 다음 단계로 간단한 자바 클라이언트를 구현해보자, RDBMS를 이용하기 위해서 JDBC 드라이버를 사용한다면, mongodb는 전용 드라이버 mongo-java-driver 를 제공한다.
이 예제에서는 별도로 설치하기 보다는 아래와 같이 maven 빌드 스크립트에 dependency를 추가하여, 빌드시에 자동으로 라이브러리가 로딩 되도록 한다.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>mongodb</groupId> <artifactId>simplemongo</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging>
<name>simplemongo</name> <url>http://maven.apache.org</url>
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
<dependencies> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java-driver</artifactId> <version>2.10.1</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.1</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-eclipse-plugin</artifactId> <configuration> <downloadSources>true</downloadSources> <downloadJavadocs>true</downloadJavadocs> </configuration> </plugin>
</plugins> </build> </project>
|
다음은 localhost에 있는 mongodb instance에 하나의 document(RDBMS로 치면 row)를 insert하는 클라이언트 프로그램 예제이다.
package com.terry; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.MongoClient; import com.mongodb.ServerAddress;
public class SimpleMongo {
MongoClient mongoClient = null; DB db=null;
public void mongoTest(String ip,int port,String dbname) throws Exception{
mongoClient = new MongoClient(new ServerAddress(ip,port)); db = mongoClient.getDB(dbname);
DBCollection userTable = db.getCollection("userTable"); BasicDBObject doc = new BasicDBObject("name", "MongoDB"). append("type", "database"). append("count", 1). append("info", new BasicDBObject("x", 203).append("y", 102));
userTable.insert(doc); }
public static void main(String args[]) throws Exception{ SimpleMongo testRunner = new SimpleMongo(); testRunner.mongoTest("localhost", 27017, "testdb"); } }
|
간단한 예제이기 때문에 몇가지만 설명을 하면
com.mongodb.DB는 mySQL의 DB등과 같이, RDBMS의 DB의 개념을 표현한다. 그래서 mongoDB에 연결한후에, db를 getDB를 통해서 연결한다.
mongoDB에서 테이블은 collection이라는 개념으로 존재한다. Table에 insert를 하기 위해서는 getCollection 메서드를 사용해서 해당 테이블 객체를 가지고 온후, Json Object를 만들어서 Table (Collection)에 insert를 하면 된다.
출처: https://bcho.tistory.com/742 [조대협의 블로그]
소개
MongoDB는 C++로 작성된 오픈소스 문서지향(Document-Oriented) 적 Cross-platform 데이터베이스이며, 뛰어난 확장성과 성능을 자랑합니다. 또한, 현존하는 NoSQL 데이터베이스 중 인지도 1위를 유지하고있습니다.
NoSQL?
흔히 NoSQL이라고 해서 아, SQL이 없는 데이터베이스구나! 라고 생각 할 수도 있겠지만, 진짜 의미는 Not Only SQL 입니다. 기존의 RDBMS의 한계를 극복하기 위해 만들어진 새로운 형태의 데이터저장소 입니다. 관계형 DB가 아니므로, RDMS처럼 고정된 스키마 및 JOIN 이 존재하지 않습니다.
Document?
Document Oriented 데이터베이스라는데.. 여기서 말하는 Document가 뭘까요? 문서? 이게 그냥 ‘문서’ 로 번역해버리면 조금은 애매합니다. 문서라고 하면 보통 워드/엑셀에 사용되는 그런 문서가 떠오르는데요, 그것과는 다릅니다. Document는 RDMS의 record 와 비슷한 개념인데요, 이의 데이터 구조는 한개이상의 key-value pair 으로 이뤄져있습니다. MongoDB 샘플 Document를 확인 해 볼까요?
{ "_id": ObjectId("5099803df3f4948bd2f98391"), "username": "velopert", "name": { first: "M.J.", last: "Kim" } }
여기서 _id, username, name 은 key 이고 그 오른쪽에 있는 값들은 value 입니다.
_id 는 12bytes의 hexadecimal 값으로서, 각 document의 유일함(uniqueness)을 제공합니다.
이 값의 첫 4bytes 는현재 timestamp, 다음 3bytes는 machine id, 다음 2bytes는 MongoDB 서버의 프로세스id, 마지막 3bytes는 순차번호입니다 추가될때마다 값이 높아진다는거지요.
Document는 동적(dynamic)의 schema 를 갖고있습니다. 같은 Collection 안에 있는 Document 끼리 다른 schema 를 갖고 있을 수 있는데요, 쉽게 말하면 서로 다른 데이터 (즉 다른 key) 들을 가지고 있을 수 있습니다.
Collection?
Collection은 MongoDB Document의 그룹입니다. Document들이 Collection내부에 위치하고 있습니다. RDMS의 table과 비슷한 개념입니다만 RDMS와 달리 schema를 따로 가지고 있지않습니다. Document 부분설명에 나와있듯이 각 Document들이 동적인 schema를 가지고 있으니까요
Database?
Database는 Collection들의 물리적인 컨테이너입니다. 각 Database는 파일시스템에 여러파일들로 저장됩니다.
RDMS와의 비교
RDMS 라는 키워드가 생소하신분들을 위하여 먼저 이에 대한 간단한 설명을 드리겠습니다. Relational Database Management System (관계형 데이터베이스 관리 시스템) 은 행과 열로 된 2차원의 table로 데이터를 관리하는 데이터베이스 시스템입니다. Mysql, Oracle Database, DB2 등 시스템들이 RDMS에 속하죠.
RDBMS | MongoDB |
Database | Database |
Table | Collection |
Tuple / Row | Document |
Column | Key / Field |
Table Join | Embedded Documents |
Primary Key | Primary Key (_id) |
Database Server & Client | |
mysqld | mongod |
mysql | mongo |
장점
- Schema-less (Schema가 없다. 같은 Collection 안에 있을지라도 다른 Schema를 가지고 있을 수 있다)
- 각 객체의 구조가 뚜렷하다
- 복잡한 JOIN 이 없다.
- Deep Query ability (문서지향적 Query Language 를 사용하여 SQL 만큼 강력한 Query 성능을 제공한다.
- 어플리케이션에서 사용되는 객체를 데이터베이스에 추가 할 때 Conversion / Mapping이 불필요하다.
MongoDB 설치
윈도우
MongoDB 공식 홈페이지의 다운로드 페이지에서 MSI 파일로 설치하면
C:\Program Files\MongoDB\Server\3.2\bin\ 에 설치됩니다.
CMD 창을 열어서 디렉토리로 들어가 mongod 를 실행하면 서버가 실행됩니다.
기본 데이터베이스 디렉토리가 C:\data\db 이므로 실행 전에 폴더를 수동으로 만들어주셔야합니다.
Microsoft Windows [Version 10.0.10586] (c) 2015 Microsoft Corporation. All rights reserved. C:\Users\Velopert>cd C:\Program Files\MongoDB\Server\3.2\bin C:\Program Files\MongoDB\Server\3.2\bin>mkdir C:\data\db C:\Program Files\MongoDB\Server\3.2\bin>mongod
데이터베이스 디렉토리를 변경하고싶다면 다음과같이 실행하면 됩니다.
C:\Program Files\MongoDB\Server\3.2\bin> mongod --dbpath "c:\custom_folder"
매번 MongoDB 설치 경로로 이동하는게 귀찮다면, 해당 디렉토리를 환경변수의 PATH 에 추가하세요.
(윈도우 10 이하 버전에서는
기존 값 ; C:\Program Files\MongoDB\Server\3.2\bin 이런식으로 수정해야합니다.)
리눅스
이 포스트에서는 Ubuntu 에서 MongoDB 설치하는 과정을 살펴보도록하겠습니다.
다른 리눅스 디스트로를 사용하시는분들은 https://docs.mongodb.org/manual/installation/ 을 참조해주세요.
주의: Cloud9 를 사용하신다면 1번과 2번은 생략하셔도 됩니다.
1. MongoDB Pulbic GPG Key 등록
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv EA312927
2. MongoDB 를 위한 list file 생성 (자신의 Ubuntu 버전에 맞게 입력하세요)
# Ubuntu 12.04 $ echo "deb http://repo.mongodb.org/apt/ubuntu precise/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list # Ubuntu 14.04 $ echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.2 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.2.list
3. apt-get 을 이용하여 설치
$ sudo apt-get update # latest stable version 설치 $ sudo apt-get install -y mongodb-org
4. 서버 실행
$ sudo service mongod start # 서버가 제대로 실행됐는지 확인 $ cat /var/log/mongodb/mongod.log # [initandlisten] waiting for connections on port <port>
기본 포트는 27017 이며, 방화벽을 사용하시는분들은 해당 포트를 Open 해주세요.
포트는 /etc/mongod.conf 에서 변경 가능합니다.
OS X
brew update brew install mongodb mkdir -p /data/db mongod # dbpath 지정 mongod --path <path>
자세한 내용: https://docs.mongodb.org/manual/tutorial/install-mongodb-on-os-x/
MongoDB 서버 접속
터미널에서 mongo 를 입력하세요.
(윈도우에서는 환경변수를 설정하지 않았다면 설치 경로에 이동 후 입력하세요)
$ mongo MongoDB shell version: 3.2.1 connecting to: test >
Data Modelling
MongoDB에서의 명령어들을 배우기전에, MongoDB에서 데이터를 모델링의 기본을 배워보겠습니다.
schema 디자인 할 때 고려사항
- 사용자 요구 (User Requirement) 에 따라 schema를 디자인한다.
- 객체들을 함께사용하게 된다면 한 Document에 합쳐서 사용한다. (예: 게시물-덧글 과의 관계)
그렇지 않으면 따로 사용한다 (그리고 join 을 사용하지 않는걸 확실히 해둔다) - 읽을때 join 하는게아니라 데이터를 작성 할 때 join 한다.
예제
간단한 블로그를 위한 데이터베이스를 디자인한다고 가정해봅시다. 요구사항을 나열해볼까요?
– 게시글에는 작성자 이름, 제목, 내용이 담겨져있다.
– 각 게시글은 0개 이상의 태그를 가지고 있을 수 있다.
– 게시글엔 덧글을 달 수 있다. 덧글은 작성자 이름, 내용, 작성시간을 담고있다.
만약에 RDMS에서 데이터베이스 schema를 디자인한다면 이것과 비슷하겠죠?
RDMS라면,이런식으로 테이블 3개를 만들어야 효율적이라고 부르지만,
NoSQL 에선 모든걸 하나의 Document 에 넣습니다. 한번 살펴볼까요?
{ _id: POST_ID,
title: POST_TITLE,
content: POST_CONTENT,
username: POST_WRITER,
tags: [ TAG1, TAG2, TAG3 ],
time: POST_TIME comments: [ { username: COMMENT_WRITER, mesage: COMMENT_MESSAGE,
time: COMMENT_TIME },
{ username: COMMENT_WRITER,
mesage: COMMENT_MESSAGE,
time: COMMENT_TIME } ]
}