All Articles

MongoDB 를 다루면서 드는 생각 - MongoDB vs RDBMS(MySQL), cursor

부제: MongoDB vs RDBMS(MySQL), cursor

MongoDB logo

MySQL 과 같은 RDB에 익숙했지만 좌표를 저장하고 다뤄야 한다는 spatial 프로젝트를 경험하고, 기술조사를 하면서 MongoDB 의 매력에 대해 알게 되었다.

schma-free 라는 특징이 가장 인상적이었는데 몇몇 프로젝트는 이미 데이터가 900만건 이상 저장되어있고, 실시간으로 운영되고 있음에도 불구하고, column 추가의 필요성이 있어 alter table 을 실행하곤 하였다.

다행히 alter table 이후 장애는 없었지만, 과연 live 인 RDB에 이러한 행동을 하는건 올바른가? 라는 질문을 수도없이 해왔다. 이 환경에 대응할 수 없는 회사의 상황, 환경 이건 어딜 가나 맞찬가지라고 생각했다. 데이터가 실시간으로 쌓이고 있는데 그걸 어떻게 백업하고, 누락된 데이터에 대한 전처리 후처리는 어떻게 할 것인가?

이런 고민을 한번에 해결할 수 있었던 것이 MongoDB 였다. column이 아닌 field 였고, table 이 아닌 document json 이기 때문에 내 domain 에 field 를 하나 추가하면 된다. 지금 운영중인 DB 에 문서마다 field 의 차이가 있다.

비교

MongoDB RDBMS(MySQL)
database database
collection collection
document record or row
field column
index index
result of query is cursor result of query record

Cursor

MongoDB 는 cursor 를 반환하는데 커서를 통해 반복적으로 실제 document 를 가져올 수 있다. 이렇게 하는 이유는 결과를 client server memory 에 모두 담아두지 않아도 처리할 수 있게 하기 위해서이다.

물론 cursor 를 읽을 때 마다 서버에서 바로 document를 가져오는것은 아니다.

문서의 정의를 보면

A pointer to the result set of a query. Clients can iterate through a cursor to retrieve results. By default, cursors timeout after 10 minutes of inactivity. See Iterate a Cursor in the mongo Shell.

query 결과 set의 pointer 라고 한다. 마치 symbolic 와 같다. (C, C++을 공부했다면 무슨느낌인지 확 올듯)

즉 쿼리 결과 자체를 주면 메모리를 먹을테니 그 주소값을 주고, 필요할때 주소에 접근하여 query 의 result 를 확인하도록 하는것이다.

MongoDB 의 특징으로 다음을 언급한다.

  1. NoSQL
  2. Schema-free
  3. 비 관계형 DB

NoSQL 의 정의는 sql 을 사용하지 않는것 이지만, https://www.simba.com/drivers/mongodb-odbc-jdbc/ 와 같은것을 사용하면 sql 과 비슷하게 통신할 수 있으며, FK 까지는 아니지만 DBF 와 같은 기능을 사용하면 document 간의 관계를 어느정도 설정할 수 있다.

그리고 Aggregation 을 사용하면 join 과 같은 기능도 구현이 가능하다.

이러한 이유로 SQL 과 NoSQL 의 경계는 서서히 허물어지고 있다.

심지어 MySQL 도 document DB 와 같은 object 형식으로 질의할 수 있다.

앞으로는 점점 이 차이가 줄어들지 않을까? 생각한다.

Query

insert

db.address.insert({
	"state": "서울특별시",
	"city": "서대문구",
	"address": "홍제1동",
	"enabled": true
});

update

db.address.update({
	{address: "홍제1동"},
	{$set: {enabled: false},
	{multi: true}
})
Update address set
	enabled = false
where address = "홍제1동";

delete

db.address.remove(
	{_id: "5099803df3f4948bd2f98391"}
)
delete from address
where 
_id = "5099803df3f4948bd2f98391";

select

db.address.find(
	{address: "홍제1동"}
)
select * from address
where address = "홍제1동";

과연 MongoDB 를 사용해야 하는 이유는 무엇인가?

참고