MongoDB 사용하기

Purple·2021년 11월 19일
0

TIL

목록 보기
58/73

1. MongoDB란,

  • NoSQL database는 데이터를 행과 열이 아닌, 또다른 체계적인 방식으로 저장한다.

  • MongoDB는 대표적인 NoSQL document database이다.

  • document database는 데이터를 테이블이 아닌, 문서처럼 저장하는 database를 의미한다. 일반적으로 document database에서는 JSON 유사 형식으로 데이터를 문서화 시킨다. 각각의 document는 데이터를 필드-값(field - value pair)의 형태로 가지고있고, 컬렉션이라고 하는 그룹으로 묶어서 관리한다.

  • document 객체와 같이 데이터를 필드-값 쌍으로 저장하고 구성한다. document에서 field는 데이터의 고유한 식별자이고, 값은 주어진 식별자와 관련된 데이터를 뜻한다. 여러 필드-값으로 저장된 데이터들을 document라고 하고, document의 모음을 collection이라고 한다. 그리고 database는 여러개의 collection으로 구성된다.

  • document는 JSON(JavaScript Object Notation)형식으로 출력된다. JSON형식으로 document를 작성하기 위해서

  1. { } 중괄호로 document가 시작하고, 끝나야한다.
  2. 필드와 값이 콜론( : )으로 분리되어야하며, 필드와 값을 포함하는 쌍은 쉼표( , )로 구분된다.
  3. 문자열인 필드도 쌍타옴표(“ “)로 감싸야한다.
  • JSON 형식은 읽기 쉽고, 많은 개발자들이 사용하기 편리한 형태를 가지고 있다. 그러나 JSON은 텍스트 형식이기 때문에 읽기 쉽지만, 파싱이 느리고 메모리 사용이 비효율적이다. 그리고 JSON은 기본 데이터 타입만을 지원하기 때문에 사용할 수 있는 데이터 타입에 제약이 있다.

  • 이러한 문제점을 해결하기 위한 방안으로 BSON(Binary JSON) 형식을 도입하였다. BSON은 컴퓨터의 언어에 가까운 이진법에 기반을 둔 표현법이다. JSON보다 메모리 사용이 효율적이며 빠르고, 가볍고, 유연하다. 그리고 BSON의 사용으로 더 많은 데이터 타입을 사용 할 수 있다.

  • JSON의 장점, BSON의 장점을 활용하여 MongoDBD의 데이터는 BSON의 형태로 저장 되고, 읽기 쉬운 JSON의 형태로 출력된다.
    단순히 백업 저장을 하기 위해서라면 가볍고 빠른 BSON의 형태로 사용하는 것이 좋고, 데이터를 내보낸 후 조회를 하거나 출력을 해야한다면 사람이 읽기 쉬운 JSON의 형식이 바람직하다.

2. NoSQL 기반의 비관계형 데이터베이스를 많이 사용하는 경우

1. 비구조적인 대용량의 데이터를 저장하는 경우

NoSQL 데이터베이스는 관계에 중점을 둔 SQL 데이터베이스보다 자유로운 형태로 데이터를 저장할 수 있으므로 필요에 따라서 새로운 데이터 유형을 쉽게 추가할 수 있다. 그래서 소프트웨어 개발에 정형화되지 않은 많은 양의 데이터가 필요한 경우, NoSQL이 효율적일 수 있다.

2. 클라우드 컴퓨팅 및 저장 공간을 최대한 활용하는 경우

NoSQL 데이터베이스는 데이터베이스를 클라우드 기반으로 쉽게 분리할 수 있도록 지원하여, 저장 공간을 효율적으로 사용한다. 시스템이 커지면서 DB를 증설해야하는 시점이 오면, SQL 데이터베이스에서는 수직적 확장의 형태로 DB를 증설한다. 수직적으로 확장된 데이터베이스는 관리가 어려워질 수 있는데에 반해, NoSQL은 수평적 확장의 형태로 증설하므로, 이론상 무한대로 서버를 계속 분산시켜 DB를 증설할 수 있다.

3. 빠르게 서비스를 구축하고 데이터 구조를 자주 업데이트 하는 경우

NoSQL 데이터베이스의 경우 스키마를 미리 준비할 필요가 없어서, 개발을 빠르게 해야하는 경우에 매우 적합하다. 시장에 빠르게 프로토타입을 출시해야하는 경우나, 소프트웨어 버전별로 많은 다운타임(데이터베이스의 서버를 오프라인으로 전환하여 작업하는 시간) 없이 데이터 구조를 자주 업데이트해야하는 경우에는 일일이 스키마를 수정해주어야하는 관계형 데이터베이스 보다 NoSQL 기반의 비관계형 데이터베이스가 더 효율적이다.

3. Atlas Cloud

  • MongoDB에서는 Atlas로 클라우드에 데이터베이스를 설정한다.
  • Atlas는 GUI와 CLI로 데이터를 시각화, 분석, 내보내기, 그리고 빌드하는 데에 사용할 수 있다. 아틀라스 사용자는 클러스터를 배포할 수 있으며, 클러스터는 그룹화된 서버에 데이터를 저장한다.
  • Atlas는 레플리카 세트(Replica set)로 구성되어 있으며, 레플리카 세트는 동일한 데이터를 저장하는 몇개의 연결된 MongoDB 인스턴의 모음이다. (MongoDB 사이트에서 보면 1개의 primary와 2개의 secondary로 보인다.)
  • 인스턴스들의 모임을 클러스터라고 하며, 하나의 시스템처럼 작동한다. (클러스터를 컴퓨터들의 모임이라고 생각하면 쉽다.)
  • 단일 클러스터에서 각각의 인스턴스는 동일한 복제본을 가지고 있다. 이 모음이 레플리카 세트다.
  • cluseter가 레플리카세트 보다 더 큰 개념이다.
  • documnet나 컬렉션을 변경할 경우, 변경된 데이터의 중복 사본이 레플리카 세트에 저장된다. 이 설정 덕분에 레플리카 세트의 인스턴스 중 하나에 문제가 발생하더라도, 데이터는 그대로 유지되며, 레플리카 세트의 애플리케이션에서 나머지 작업을 할 수 있다. (나머지 레플리카 세트의 인스턴스에 저장된 데이터로 작업 가능하다.) //=> 이를 고가용성(availibility)이 있다라고 말한다. // 이 과정을 위해 클러스터(서버그룹)를 이용하여 배포할 경우, 자동으로 레플리카 세트를 생성한다.
  • 인스턴스는 특정 소프트웨어를 실행하는 로컬 또는 클라우드의 단일 머신이다. 이 경우에서 인스턴스는 클라우드에서 실행되는 MongoDB 데이터베이스이다.

4. MongoDB Basic

1. 데이터 내보내기

  • export에는 2종류가 있다: JSON형식으로 내보내기(mongoexport), BSON형식으로 내보내기(mongodump)
  • 이를 사용하기 위해서는 Atlas Cluster URI가 필요하다. 이 URI는 일반 웹의 URI와 형식이 같고, username, password, cluster 주소로 이루어져 있다.
  • mongodump를 하는 경우에는 별다른 쿼리가 없지만,
    mongoexport를 하는 경우에는 해당 데이터베이스의 컬렉션이름, 파일 이름까지 정확하게 작성해주어야한다.
  • mongoexport는 JSON형식의 데이터를 아틀라스 클러스터에서 내보낼 때 사용한다. 단, 내보낼 때 아틀라스 클러스터에 컬렉션을 더하는 대신, 아틀라스 클러스터 외부에 데이터 복사본을 만든다.

2. 데이터 가져오기

  • import도 2종류가 있다. JSON 형식의 데이터를 가져올 경우(mongoimport), BSON형식의 데이터를 가져올 경우(mongorestore)
  • mongoimport는 데이터베이스를 아틀라스 클러스터로 가져올 수 있도록 한다. 이때 데이터는 JSON일 수도 있고, 지원되는 다른 데이터형식일 수 있다.
  • mongorestore는 mongodump가 생성한 BSON 형식의 데이터를 가지고 온다.

3. Document

  • MongoDB의 모든 document는 _id 필드를 기본값으로 가지고 잇다. 이 _id 필드의 값은 각 document를 구별하는 역할을 한다. document 내부의 필드와 값이 똑같다 할지라도, _id 값이 다르면 서로 다른 document로 간주한다.

5. MongoDB 사용하기

1. show dbs

: 사용가능한 데이터베이스들이 보인다.

2. use 데이터베이스명

: 사용할 데이터베이스를 선택한다.

3. show collections

: 데이터베이스 안의 컬렉션 리스트를 볼 수 있다.

4. db

: 현재 사용하고 있는 데이터베이스 이름을 보여준다.

5. CREATE

  • _id 는 ObjectId타입(12byte, 24char)의 값으로 되어있다.
  • db.zips.insert({삽입하려는 데이터}) : zips라는 컬렉션에 삽입할 수 있는 명령어
  • insert 명령어의 결과물로 하단에 WriteResult가 출력된다. 그 중 nInserted라는 항목은 삽입된 document의 수를 의미한다. 이 숫자가 0이라면 에러가 발생해서 document 추가에 실패했다는 것을 의미한다. _id가 같은 값이 있다면 실패했을 것이다. _id필드 외 똑같은 document는 다른 _id로 추가되겠지만, _id값은 같고 그 외의 값이 다른 document를 추가하려고 하면 실패한다.
  • 존재하지 않은 컬렉션이름을 적고 insert 명령을 실행하면 컬렉션이 새로 생기면서 document가 생성된다.
  • 한번에 여러개의 document를 삽입하기 위해서는 배열 안에 해당하는 document를 담아야한다. db.zips.insert([{“test”:”1”},{“test”:”2”},{“test”:”3”}]) 그러면 순서대로 document가 추가된다. 만약 0번째,1번째에서 에러가 발생하면 2번째 document가 정상적인 document라 하더라도 zips 컬렉션에 추가되지 않는다.
  • 만약 순서에 상관없이 document를 추가하고 싶다면, db.zips.insert([{“test”:”1”},{“test”:”2”},{“test”:”3”}],{“ordered”:false}) 라고 뒤에 ordered를 붙여주면 된다. 이렇게 순서없이 삽입되면, 0번째,1번째에서 에러가 발생하더라도 2번째가 정상적인 document라 하면, 1개의 documentary zips 컬렉션에 추가될 것이다.

6. READ

  • db.컬렉션명.find(<쿼리문>) 예) db.zips.find({“state”:”NY”}) => zips라는 컬렉션에서 뉴욕주라는 조건을 만족하는 데이터를 찾는다. 이때 이미 use를 사용하여 필요한 데이터베이스 공간으로 이동했기때문에, 사용할 데이터베이스의 이름을 특정해서 작성할 필요는 없다. 결과는 JSON형식으로 화면에 출력되고, 실제결과물이 훨씬 더 많다면 랜덤하게 20개만 선택되서 보일것이다.
  • 해당 조건에 맞는 다음 20개의 document를 조회하기 위해서는 it 명령어를 입력하면 된다. it의 iterate의 줄임말이다.
  • 조건이 여러개라면 콤마로 붙여서 계속 객체 안에 적어주면 된다. db.zips.find({“state” : “NY”, “city” : “NEW YORK”})
  • 만약, 데이터 베이스의 모든 데이터를 조회하고 싶다면, find 명령어를 조건 쿼리문 없이 써주면 된다. db.zips.find()
  • 만약, 조회한 데이터의 수를 알고 싶다면, count() 명령어를 붙여주면 된다.
  • 1개의 무작위 데이터를 선택하고 싶다면, findOne()을 사용하면 된다.
  • 조건 입력시 대소문자를 구분하니 주의하자!!!!

7. UPDATE

  1. updateMany: 쿼리문과 일치하는 모든 document를 업데이트
    이미 존재하는 document중 원하는 document의 특정필드를 업데이트 하고 싶을 때, 예를 들어db.zips.updateMany({“city”:”ALPINE”},{“$inc”:{“pop”:10}}) -> zips라는 collection의 ALPINE city의 document를 업데이트(updateMany)하고 싶고, 업데이트 할 필드는 pop이며, 10씩 증가(increment : $inc) 시키고 싶다.
    그러면 matchedCount와 modifiedCount를 통해 몇개의 document가 찾아졌고, update 되었는지 알 수 있다. 두개의 count가 같으면 성공한 것이다.
  2. updateOne: 주어진 기준에 맞는 다수의 document 중 첫번째 document 하나만 업데이트
    한개의 document를 update할때는 굳이 $inc를 쓰지 않아도 된다. $set연산자를 사용하면 주어진 필드에 지정된 값을 업데이트 할 수 있다. 예를 들어
    zip이 12534인 document의 pop을 6235로 바꾸려고 하면,
    db.zips.updateOne({“zip":"12534"},{"$set":{"pop":6235}}) 라고 입력하면 된다.
  3. 만약 필드 이름을 잘못 작성하였는데, 해당 필드 이름이 기존에 없는 이름이면 해당 필드는 추가되서 document안에 같은 값을 가지는 새로운 이름의 필드가 생긴다. 예를들어 실수로 기존필드의 “pop”이 아닌 “population”으로 명령하면, pop은 그대로 존재하고, population이 생긴다.

8. DELETE

  1. deleteOne: 주어진 기준에 맞는 다수의 document 중 첫번째 document 하나를 삭제한다. 검색 쿼리문의 조건에 맞는 다수의 document가 있다면, 의도하지 않은 document가 삭제될 수도 있으니, deleteOne()을 사용하는 경우 _id 값으로 쿼리해 온 document를 삭제 하는 것이 좋다.
    db.inspections.deleteOne({“_id”: “아이디 이름”})
    그러면 { acknowledged: true, deletedCount: 1 }라고 삭제된 결과를 알려준다.
  2. deleteMany: 쿼리문과 일치하는 모든 document를 삭제한다. 기준을 충족하는 document가 많을 경우 deleteMany를 사용하여 다수의 document를 삭제할 수도 있다.
  3. db.컬렉션이름.drop()은 컬렉션을 삭제하는 명령어이다. 이 명령어가 성공하게 되면 true라고 짧게 알려준다. 그리고 다시 show collections 했을 때 삭제된 collection은 보이지 않을 것이다.
profile
다시 보면, 더 많은 것들이 보인다.

0개의 댓글