[mongodb] MongoDB CRUD 동작의 이해

이번 포스팅은 몽고DB의 Document 및 Collection의 정의 그리고 CRUD 동작에 대해 알아보고자 합니다.

1. Document & Collection 정의

1.1. Document

몽고DB Document는 key/value로 이뤄진 한쌍의 값들을 가지고 있는 오브젝트입니다. JSON과 흡사하게 구성하며 다음처럼 구성이 가능하죠.

/* Document Sample */
{
	name: "동민", // key : value
	age: 29,
	status: "A+",
	groups: ["programmer", "developer"]
}

Document들은 disk에 저장될 때 BSON(json binary format)으로 저장된다고 합니다. 자세한건 나중에 들여다 보도록 합시다. Document를 구성할때 다음처럼 만들 수도 있습니다.

/* Document Sample */
var obj =
{
	/* _id: 1234 등도 가능합니다. */
	_id: ObjectId("012345678910111213141516"),
	name: "동민",
	age: 29,
	status: "A+",
	groups: ["programmer", "developer"],
	birth: new Date('nov 11, 1986'),
	wisdom: NumberLong(9999999)
}

위처럼 생성한 obj 변수 값을 한번 몽고 DB에 삽입해 봅시다.

db.t.insert( obj )

그 후 find() 명령어를 통해 확인 해보면 obj 값이 t 콜렉션에 삽입 되어 있는 것을 확인 할 수 있습니다. _id 필드는 별도 지정을 할 수 있지만 ObjectId()를 사용한다면 자릿수는 지켜줘야 합니다.

1.2. Collection

모든 Document들은 Collection에 속해 있어야 합니다. 콜렉션Collection이란 관계되어 있는 Document들의 그룹을 뜻합니다.

2. Query

2.1. MongoDB Query vs RDBMS Query

몽고DB에서 쿼리Query는 RDBMS의 Query와 동일한 개념으로 보입니다. 몽고DB에선 특별한 기준을 가진 Document들을 추출해 콜렉션으로 만들 수 있죠. 쿼리에는 특별한 기준값(Query Criteria)과 추출할 값(projection), 그리고 Collection과 커서(cursor)를 정의할 수 있습니다. 예제 쿼리를 만들어봅시다.

/* sample query */
db.tbl.find(             collection
{ num: { $gt: 29} },     query criteria
{ val1: 1, val2: 1 }     projection
).limit(10)              cursor modifier

위와 같은 쿼리를 기존의 RDBMS SQL로 나타내면 아래처럼 됩니다.

/* sample query */
select _id, val1, val2 -- projection
  from tbl             -- table
 where age > 29        -- select criteria
 limit 5               -- cursor modifier

쿼리의 처리 순서는 Collection 선택 ▶ Query Criteria 수행 ▶ Modifier 수행 순입니다. 각각 구문이 수행 될때마다 콜렉션이 추출됩니다.

2.2. Query selection operator

몽고DB의 쿼리 중에서 $gt 같은 연산자를 쿼리 선택 연산자라고 합니다. 자세한 내용은 http://docs.mongodb.org/manual/reference/operator/에서 operator 관련 정보를 확인해 보세요.

2.3. Projection

일반적인 SQL 쿼리문에서 "select" 구문에 해당하는 Projection은 find() 메소드의 두번째 인자값에 해당합니다.

/* sample query */
db.tbl.find(
{ num: { $gt: 29} },
{ val1: 1, val2: 1 }     projection
).limit(10)

위의 코드에서 "projection"으로 표시된 부분입니다. 여기서 유의할 것이 있는데 만약 _id 필드를 projection에서 제외하면 추후에 projection을 합칠 때 문제가 생깁니다. 이건 추후에 다시 살펴보기로 합니다.

위 구문에서 val1 필드 값인 1은 추출한 콜렉션에서 val1 필드를 포함하고 반대로 val1 필드 값이 0이라면 추출한 콜렉션에서 val1 필드를 제외합니다. 따라서 위 구문은 val1과 val2 필드를 포함하겠다는 뜻이 됩니다.

3. Query Examples

3.1. Example1

db.t_col.find({ "view_count": { $gt: 29 }, { "title":0 })

추출할 콜렉션에서 특정 필드를 제외하는 쿼리입니다.

위의 쿼리를 실행하면 view_count값이 29보다 큰 document들을 선택하고, 선택된 document들의 필드 중 "title" 필드를 제외합니다.

3.2. Example2

db.t_col.find({ "view_count": { $gt: 29 }, { "title":1, "cont":1 })

2개의 필드와 _id 필드를 포함하는 쿼리입니다.

위의 쿼리를 실행하면 view_count값이 29보다 큰 document들을 선택하고, 선택된 document들의 필드 중 "title", "cont", "_id" 필드만 가져옵니다.

3.3. Example3

db.t_col.find({ "view_count": { $gt: 29 }, { "title":1, "cont":1, "_id":0 })

2개의 필드를 포함하고 _id 필드를 제외하는 쿼리입니다.

위의 쿼리를 실행하면 view_count값이 29보다 큰 document들을 선택하고, 선택된 document들의 필드 중 "_id"필드를 제외하고 "title", "cont" 필드만 가져옵니다.

4. Data Modification

데이터 수정이란 몽고DB 내에서 create, update, delete 동작을 뜻합니다. 이 동작들은 하나의 콜렉션 내부의 데이터를 수정합니다. update 및 delete는 document들을 업데이트 하거나 삭제할 수 있습니다.

4.1. Insert

몽고DB에서 db.collection_name.insert() 메소드는 콜렉션에 새로운 document를 추가합니다.

/* sample query */
     collection
db.tbl.insert(
	 document
	{
		name:"JDM",   field : value
		age: 29       field : value
	}
)

우선 콜렉션을 선택 후 document을 삽입합니다. insert()구문의 첫번째 인자를 document 객체로 넣으면 됩니다. 위의 구문을 RDBMS SQL로 나타내면 아래와 같습니다.

/* sample query */
insert into tbl            -- table
            ( name , age ) -- columns
values      ( "JDM", 29 )  -- values

여기에서 주의할 것은 _id 필드를 지정하지 않았다면 자체적으로 _id 필드값을 생성해서 같이 추가한다는 것입니다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

만약 _id 필드 값을 임의로 설정했다면 반드시 콜렉션 내에서 고유한 값을 지정하도록 합시다. 하지만 이를 지키지 않는다면 몽고 DB에서는 _id 값이 겹칠 경우 duplicate key exception을 보여줄겁니다.

4.2. Update

몽고DB에서 db.collection_name.update() 메소드는 콜렉션에 있는 문서를 수정합니다.

/* sample query */
     collection
db.tbl.update(
	{ age: { $gte: 29 },        update criteria
	{ $set: { grade:"SSS" } },  update action
	{ multi : true}             update option
)

위와 같은 쿼리를 RDBMS SQL로 나타내면 아래와 같습니다.

/* sample query */
update tbl           -- table
set    grade = 'SSS' -- update action
where  age >= 29     -- update criteria

기본적인 update 쿼리의 동작은 하나의 document만을 업데이트 합니다. 그러나 multi 옵션을 true로 주게 되면 update() 메소드에 추출된 모든 document들을 업데이트 합니다.

만약에 기존에 있던 document보다 큰 사이즈의 document를 업데이트 한다면 디스크를 재할당하는 연산도 추가됩니다.

하지만 update 쿼리에도 예외가 있을 수 있는데 그것은 다음과 같습니다.

  • _id 필드값이 document 내에서 항상 첫번째 필드인 경우
  • document 내의 필드들을 재정렬한 결과에서 별칭(renaming)을 포함한 경우

4.3. Update Option - upsert

update 쿼리를 실행을 했지만 반영된 document들이 없는 경우 쿼리는 무용지물이 됩니다. 이를 대비해서 몽고DB에서는 upsert:true 구문을 제공하고 있습니다.

이 구문은 update할 document가 없는 경우 document를 insert 해주는 옵션입니다. 만약 update 쿼리에 매칭된 document가 있는 경우 매칭된 document들을 수정합니다.

4.4. Remove

몽고DB에서 db.collection_name.remove() 메소드는 콜렉션 내의 매칭된 document들을 삭제합니다. 예를 들면 다음과 같은 쿼리가 되겠습니다.

/* sample query */
     collection
db.tbl.remove(
	{ age: { $gte: 29 } }  remove criteria
)

위와 같은 쿼리를 RDBMS SQL로 나타내면 아래와 같습니다.

/* sample query */
delete from tbl      -- table
where  age >= 29     -- delete criteria

일반적으로 삭제 동작은 조건에 매칭되는 모든 document들을 삭제합니다. 그러나 별도의 옵션을 통해 하나의 document를 삭제하거나 삭제할 document의 개수를 정할 수 있습니다.

4.5. Remove All Documents

만약 모든 document를 지우고 싶다면 아래와 같은 구문을 입력합니다.

db.collection_name.remove({})

다만 drop() 메소드가 더 효율적일 수 있습니다. drop() 메소드는 모든 document들과 포함되어 있는 인덱스들까지 삭제합니다.

4.6. Remove a Single Document

만약 조건에 맞는 document 하나만을 삭제하고 싶은 경우 다음과 같은 구문을 사용합니다.

db.collection_name.remove({ name:"JDM" }, 1 )

5. Isolation of Write Operations

하나의 document에서의 수정은 언제나 원자성(atomic)을 가집니다. document내에서 내부의 sub document도 포함합니다.

만약 여러개의 document를 수정한다면 전체의 동작에 대해서는 원자성을 보장하지 않습니다. 하지만 개별의 document는 원자성을 가집니다. 다른 동작들은 원자성을 가지지 않습니다. 그러나 분리 연산자($isolated)를 사용해 여러 document들에 영향을 줄 수도 있습니다. 자세한 내용은 다음 링크에서 확인 할 수 있습니다.

http://docs.mongodb.org/manual/reference/operator/update/isolated

분리 연산자를 사용하면 RDBMS의 트랜잭션처럼 "all or nothing" 결과를 가져옵니다. 하지만 클러스터(sharede clusters) 환경에서는 동작 하지 않습니다.

* 이 포스팅에 언급은 안했지만 원문에는 있는 db.collection_name.save() 메소드와 분리 연산자($isolated)는 시간이 되면 별도로 포스팅 해보고 싶네요.

6. Reference

[출처] https://jdm.kr/blog/18

 

 

 

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
공지 오라클 기본 샘플 데이터베이스 졸리운_곰 2014.01.02 86125
공지 [SQL컨셉] 서적 "SQL컨셉"의 샘플 데이타 베이스 SAMPLE DATABASE of ORACLE 가을의 곰을... 2013.02.10 78629
공지 [G_SQL] Sample Database 가을의 곰을... 2012.05.20 95345
42 [ms sql server] SQL Server 2019 Express 외부 접속을 위한 처리 file 졸리운_곰 2024.07.27 1602
41 [ms sql server] MS-SQL 2019 Express 와 SSMS 를 설치하고 DB, 사용자 추가 후 네트워크 설정하기 file 졸리운_곰 2024.07.27 1520
40 데이터 입력/수정/삭제를 한 번에 처리할 수 있는 MERGE에 대해 알아보자 file 졸리운_곰 2020.09.10 1854
39 SQL Server PIVOT : ms sql server Row Column Pivot 로우 컬럼변환 file 졸리운_곰 2020.06.13 1614
38 MSSQL 로우를 컬럼으로 졸리운_곰 2020.06.13 1663
37 [MS SQL] FROM - PIVOT 및 UNPIVOT 사용 졸리운_곰 2020.06.13 957
36 [MSSQL] 3개 이상 테이블 조인 file 졸리운_곰 2020.05.16 1601
35 [MSSQL] 경고: 집계 또는 다른 SET 연산에 의해 Null 값이 제거되었습니다. 졸리운_곰 2020.01.31 1673
34 [MSSQL] 경고: 집계 또는 다른 SET 작업에 의해 Null 값이 제거되었습니다. file 졸리운_곰 2020.01.31 1876
33 MS-SQL 트리거 사용하기 (간략 공략!?!?) file 졸리운_곰 2020.01.31 1455
32 [ms sql server] T-SQL 저장 프로시져 만들기 : CREATE PROCEDURE(Transact-SQL) file 졸리운_곰 2020.01.27 1924
31 [ms sql server] 저장 프로시저 만들기 file 졸리운_곰 2020.01.27 1102
30 Installing Microsoft SQL Server in Docker SQL Server and Docker file 졸리운_곰 2020.01.26 9140
29 MS SQL Stored Procedure file 졸리운_곰 2020.01.26 1687
28 [MSSQL] 저장 프로시저 만들기 실습 file 졸리운_곰 2020.01.26 1667
27 MS-SQL 에서 한글 검색이 안되는 경우 졸리운_곰 2020.01.24 1423
26 mssql 2012 언어변경 질문드립니다. file 졸리운_곰 2020.01.23 1501
25 [MS-SQL] 쿼리문 정리 file 졸리운_곰 2020.01.23 1938
24 [DB/Docker/MSSQL] Docker + MSSQL 개발하기 졸리운_곰 2020.01.23 1368
23 Linux에서 환경 변수를 사용하여 SQL Server 설정 구성 file 졸리운_곰 2020.01.23 1241
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED