티스토리 뷰
몽고DB는 매우 강력하면서도 진입장벽이 낮다. 몽고 DB의 기본 개념을 소개한다.
- 몽고DB 데이터의 기본 단위는 도큐먼트이며, 이는 관계형 데이터베이스의 행과 유사하다(하지만 더 다양한 자료 표현이 가능하다.)
- 같은 맥락에서 컬렉션(collection)은 동적 스키마(dynamic schema)가 있는 테이블과 같다.
- 몽고DB의 단일 인스턴스는 자체적인 컬렉션을 갖는 여러 개의 독립적인 데이터베이스를 호스팅한다.
- 모든 도큐먼트는 컬렉션 내에서 고유한 특수키인 "_id"를 가진다.
- 몽고 DB는 몽고 셸(The mongo Shell)이라는 간단하지만 강력한 도구와 함께 배포된다. mongo 셸은 몽고DB 인스턴스를 관리하고 몽고DB 쿼리 언어로 데이터를 조작하기 위한 내장 자원을 제공한다. 또한 사용자가 다양한 목적으로 자신의 스크립트를 만들고 로드 할수 있는 완전한 기능의 자바스크립트 해석기다.
2.1 도큐먼트
몽고DB의 핵심은 정렬된 키와 연결된 값의 집합으로 이뤄진 도큐먼트다. 도큐먼트 표현 방식은 프로그래밍 언어마다 다르지만 대부분의 언어는 맵(map), 해시(hash), 딕셔너리(dictionary)와 같이 도큐먼트를 자연스럽게 표현하는 자료구조를 가진다. 예를 들어 자바스크립트에서 도큐먼트는 객체로 표현된다.
{"greeting" : "Hello, world!"}
이 간단한 도큐먼트는 "greeting"이라는 키에 연결된 "Hello, World!"라는 값을 가진다. 대부분의 도큐먼트는 이보다 복잡한 다중 키/값 쌍을 가진다.
{"greeting" : "Hello, world!", "views" : 3}
위 예제에서 볼 수 있듯 도큐먼트의 값은 단지 blob형이 아니다. 값은 데이터형이어야 한다. (또는 내장 도큐먼트 전체가 되기도 한다. 2.6.4 '내장 도큐먼트' 참조). 예제에서 "greeting"의 값은 문자열이며 "views"의 값은 정수다.
도큐먼트의 키는 문자열이다. 다음 예외 몇 가지를 제외하면 어떤 UTF-8 문자든 쓸 수 있다.
- 키는 \0(null 문자)을 포함하지 않는다. \0은 키와 끝을 나타내는 데 사용된다.
- .과 $ 문자는 몇 가지 특별한 속성을 가지며 이후 장에서 설명할 특정 상황에만 사용해야 한다. 이 문자들은 보통 예약어(reserved word)로 취급해야 하며 부적절하게 사용하면 드라이버에서 경고를 발생한다.
몽고 DB는 데이터형과 대소문자를 구별한다. 예를 들어 다음 두 도큐먼트는 서로 다르다.
{"count": 5}
{"count": "5"}
다음예제도 마찬가지다.
{"count": 5}
{"Count": 5}
또한 몽고 DB에서는 키가 중복될 수 없음을 기억하자. 예를 들어 다음 도큐먼트는 올바른 도큐먼트가 아니다.
{"greeting": "Hello, world!", "greeting": "Hello, MongoDB!"}
2.2 컬렉션
컬렉션 은 도큐먼트의 모음이다. 몽고DB의 도큐먼트가 관계형 데이터베이스의 행에 대응된다면 컬렉션은 테이블에 대응된다고 볼 수 있다.
2.2.1 동적 스키마
컬렉션은 동적스키마를 가진다. 하나의 컬렉션 내 도큐먼트들이 모두 다른 구조를 가질 수 있다는 의미다. 예를 들어 다음 도큐먼트들을 하나의 컬렉션에 저장할 수 있다.
{"greeting": "Hello, world!", "views": 3}
{"signoff": "Good night, and good luck"}
도큐먼트들의 키, 키의 개수, 데이터형의 값은 모두 다르다. 다른 구조의 도큐먼트라도 같은 컬렉션에 저장할 수 있는데 '왜 별도의 컬렉션이 필요하지?'라고 생각할 수도 있다. 이에 대한 몇 가지 합당한 이유가 있다.
- 같은 컬렉션에 다른 종류의 도큐먼트를 저장하면 개발자와 관리자에게 번거로운 일이 생길 수도 있다. 각 쿼리가 특정 스키마를 고수하는 도큐먼트를 반환하는지, 혹은 쿼리한 코드가 다른 구조의 도큐먼트를 다룰 수 있는지 확실히 확인하자. 예를 들어 블로그 게시물을 쿼리한 데이터 중 작성자 데이터만 제거하려면 상당히 번거롭다.
- 컬렉션별로 목록을 뽑으면서 한 컬렉션 내 특정 데이터형별로 쿼리해서 목록을 뽑을 때보다 훨씬 빠르다. 예를 들어 "요약", "전체", "뚱뚱이 원숭이"와 같은 컬렉션형을 값으로 하는 "type" 키가 도큐먼트 내에 있다면, 단일 컬렉션에 들어 있는 값을 찾기보다 세 컬렉션 중에서 올바른 컬렉션을 쿼리하는 편이 훨씬 빠르다.
- 같은 종류의 데이터를 하나의 컬렉션에 모아두면 데이터 지역성(data locality)에도 좋다. 블로그 게시물 여러 개를 뽑는 경우, 게시물과 저자 정보가 섞인 컬렉션보다 게시물만 들어 있는 컬렉션에서 뽑을 때 디스크 탐색 시간이 더 짧다.
- 인덱스를 만들면 도큐먼트는 특정 구조를 가져아 한다.(고유 인덱스인 경우 특히 더 그렇다) 이러한 인덱스는 컬렉션별로 정의한다. 같은 유형의 도큐먼트를 하나의 컬렉션에 넣음으로써 컬렉션을 효율적으로 인덱싱할 수 있다.
스키마를 만들고 관련된 유형의 도큐먼트를 그룹화 하는 데는 타당한 이유가 있다. 애플리케이션 스키마는 기본적으로 필요하지 않지만 정의하면 좋다. 몽고 DB의 도큐먼트 유효성 검사기능과 객체-도큐머트 매핑 라이브러리를 이용하며 , 이는 많은 프로그래밍 언어에서 사용 가능하다.
2.2.2 네이밍
컬렉션은 이름으로 식별된다. UTF-8 문자열이든 쓸 수 있지만 몇 가지 제약 조건이 있다.
- 빈 문자열("")은 유효한 컬렉션명이 아니다.
- \0(null 문자)은 컬렉셔명의 끝을 나타내는 문자이므로 컬렉션명에서 사용할 수 없다.
- system.으로 시작한느 컬렉션명은 시스템 컬렉션에서 사용하는 예약어로 사용할 수 없다.
- 사용자가 만든 컬렉션은 이름에 예약어인 $를 포함할 수 없다.
서브컬렉션
서브컬렉션의 네임스페이스에 .(마침표) 문자를 사용해 컬렉션을 체계화한다.
ex) blog.posts, blog.authors
이는 단지 체계화를 위함이며 blog 컬렉션이나 자식 컬렉션과는 아무런 관계가 없다. 심지어 blog 컬렉션은 없어도 된다.
- 큰파일은 저장하는 프로토콜인 GridFS는 콘텐츠 데이터와 별도로 메타데이터를 저장하는 데 서브컬렉션을 사용한다.
- 대부분의 드라이버는 특정 컬렉션의 서브컬렉션에 접근하는 몇 가지 편리한 문법을 제공한다. 예를 들어 데이터베이스 셸에서 db.blog는 blog컬렉션을 db.blog.posts는 blog.posts 컬렉션을 보여준다.
2.3 데이터베이스
몽고DB는 컬렉션에 도큐먼트를 그룹화할 뿐 아니라 데이터베이스에 컬렉션을 그룹 지어 놓는다. 몽고DB의 단일 인스턴스는 여러 데이터베이스를 호스팅할 수 있으며, 각 데이터베이스를 완전히 독립적으로 취급할 수 있다.
- admin : admin 데이터베이스는 인증과 권한 부여 역할을 한다.
- local: local 데이터베이스는 단일 서버에 대한 데이터를 저장한다. 복제셋(replica set)에서 local은 복제 프로세스에 사용된 데이터를 저장한다.
- config: 샤딩된 몽고DB 클러스터는 config 데이터베이스를 사용해 각 샤드의 정보를 저장한다.
컬렉션을 저장하는 데이터베이스의 이름을 컬렉션명 앞에 붙이면 올바른 컬렉션명인 네임스페이스를 얻는다.
ex) cms.blog.posts > cms 데이터베이스의 blog.posts 컬렉션 사용
2.4 몽고DB 시작
별도 작성
docker 사용법
docker pull mongo
docker images
docker run --name mongodb -v ~/mongodb/db:/data/db -d -p 27017:27017 mongo
docker exec -it mongodb bash
mongo
2.5 몽고DB 셸 소개
몽고DB는 명령행에서 몽고 DB 인스턴스와 상호작용하는 자바스크립트 셸을 제공한다. 셸은 관리 기능이나, 실행 중인 인스턴스를 점검하거나 간단한 기능을 시험하는데 매우 유용하다.
2.5.1 셸 실행
셸은 자바스크립트 해석기이며 임의의 자바스크립트 프로그램을 실행한다. 표준 자바스크립트 라이브러리의 모든 기능을 활용할 수 있고 함수를 정의하고 호출할 수도 있다.
2.5.2 몽고DB 클라이언트
셸의 진수는 독자적으로 쓸 수 있는 몽고DB 클라이언트다.
- 현재 db에 할당된 데이터베이스를 확인하려면 db를 입력한다.
- 데이터베이스를 선택하려면 use video를 입력한다.
- db.movies를 입력하면 현재 데이터베이스의 movies 컬렉션을 반환한다.
이제 컬렉션에 접근하고 거의 모든 데이터베이스 작업을 수행할 수 있다.
2.5.3 셸 기본 작업
셸에서 데이터를 조작하거나 보려면 생성, 읽기, 갱신, 삭제의 네 가지 기본적인 작업(CRUD)을 한다.
생성
insertOne 함수는 컬렉션에 도큐먼트를 추가한다. movie라는 지역변수를 생성하고 insertOne 함수를 이용해 movies 컬렉션에 저장할 수 있다.
db.movies.insertOne(move)
읽기
find와 findOne은 컬렉션을 쿼리하는 데 사용한다. 컬렉션에서 단일 도큐먼트를 읽으려면 findOne을 사용한다.
db.movies.findOne()
find와 findOne은 쿼리 도큐먼트 형태로 조건 전달도 가능하다. 따라서 쿼리에서 일치하는 도큐머트로 결과를 제한한다.
갱신
updateOne을 사용한다. updateOne의 매개변수는 최소 두 개다. 첫번쨰는 수정할 도큐먼트를 찾는 기준이고, 두 번째는 갱신 작업을 설명하는 도큐먼트다. 갱신하려면 갱신 연산자인 set을 이용한다.
db.movies.updateOne(title: "...."}, {$set: {reviews: []}})
삭제
deleteOne과 deleteMany는 도큐먼트를 데이터베이스에서 영구적으로 삭제한다. 두 함수 모두 필터 도큐먼트로 삭제 조건을 지정한다.
필터와 일치하는 모든 도큐먼트를 삭제하려면 deleteMany를 사용한다.
db.movies.deleteOne({title: "...."})
2.6 데이터형
몽고DB는 도큐먼트의 값으로 다양한 데이터형을 지원한다.
2.6.1 기본 데이터형
몽고DB는 JSON의 키/값 쌍 성질을 유지하면서 기본 타입(null, 불리언, 숫자, 문자열, 배열, 객체) 외 추가적인 데이터형을 지원한다.
null
null값과 존재하지 않는 필드를 표현하는데 사용
불리언
참과 거짓에 사용 true/false
숫자
셸은 64비트 부동소수점 수를 기본으로 사용한다. 따라서 다음 수들은 셸에서 정상이다.
{"x": 3.14}
{"x": 3}
4바이트 혹은 8바이트의 부호 정수(signed integer)는 각각 NumberInt 혹은 NumberLong 클래스를 사용한다.
{"x": NumberInt("3")}
{"x": NumberLong("3")}
문자열
어떤 UTF-8문자열이든 문자열형 표현 가능
날짜
몽고 DB는 1970년 1월 1일부터의 시간을 1/1000초 단위로 나타내는 64비트 정수로 날짜를 저장한다. 표준 시간대(time zone)는 저장하지 않는다.
{"x": new Date()}
정규표현식
쿼리는 자바스크립트의 정규 표현식 문법을 사용할 수 있다.
배열
값의 셋이나 리스트를 배열로 표현할 수 있다.
내장도큐먼트
도큐먼트는 부모 도큐먼트의 값으로 내장된 도큐먼트 전체를 포함할 수 있다.
{"x": {"foo": "bar"}}
객체 ID
객체ID는 도큐먼트용 12바이트 ID다.
이진데이터
이진 데이터는 임의의 바이트 문자열이며 셸에서는 조작이 불가하다. UTF-8이 아닌 문자열을 저장하는 유일한 방법이다.
코드
쿼리와 도큐먼트는 임으의 자바스크립트 코드를 포함할 수 있다.
{"X": function(){/*...*/}}
2.6.2 날짜
새로운 Date 객체를 생성할 때는 항상 Date()가 아닌 new Date()를 호출해야 한다. 함수로 생성자를 호출하면 (new가 포함되지 않은 것)실제 Date 객체가 아닌 날짜의 문자열 표현을 반환한다. 이는 몽고DB가 아니라 자바스크립트의 작동 방식 때문이다. 항상 Date 생성자를 주의하지 않으면 문자열과 날짜가 뒤범벅되며 삭제, 수정 쿼리 등에서 문제가 발생할 수 있다.
2.6.3 배열
배열은 정렬연산(리스트, 스택, 큐)과 비정렬 연산(셋)에 호환성 있게 사용 가능한 값이다.
{"things" : ["pie", 3.14]}
예제에서 볼 수 있듯이 서로 다른 데이터형(여기서는 문자열과 부동소수점)을 값으로 포함할 수 있다. 배열값은 일반적인 키/값 쌍을 지원하는 어떤 데이터형 값이든 될 수 있으며, 중첩 배열도 될 수 있다.
배열에 쿼리하거나 배열의 내용을 이용해 인덱스를 만들 수 있으며 배열의 내용을 수정할 수 있다.
2.6.4 내장 도큐먼트
도큐먼트는 키에 대한 값이 될 수 있는데, 이를 내장 도큐먼트라고 한다.
{
"name": "john",
"address" : {
"street" : "123 street",
"city" : "Anytown"
}
}
예제에서 address 키 에 대한 값은 street, city의 키/값 쌍을 갖는 내장 도큐먼트다. 배열과 마찬가지로 내장도큐먼트의 구조를 이해하고 인덱스르 구성하고 쿼리하며 갱신하기 위해 내장도큐먼트 내부에 접근한다.
관계형 데이터베이스에서는 이 도큐먼트가 두 개의 테이블(people과 address)에 분리된 두 개의 행으로 모델링된다. 몽고DB에서는 people 도큐먼트 내에 바로 address 도큐먼트를 내장할 수 있다. 이를 통해 더 자연스럽게 정보를 표현할 수 있다.
그러나 더 많은 데이터 반복이 생길 수 있다는 단점이 있다. 관계형데이터베이스에서는 데이터 수정시 address 하나의 테이블에서 주소를 수정하면 people에서 address 테이블을 조인하여 수정된 데이터를 보여줄 수 있다. 그러나 몽고DB는 각 사람의 도큐먼트에서 오타를 수정해야 한다.
2.6.5 _id와 ObjectId
저장된 모든 도큐먼트는 _id 키를 가진다. _id 키 값은 어떤 데이터형이여도 상관없지만 ObjectId가 기본이다. 하나의 컬렉션에서 모든 도큐먼트는 고유한 _id 값을 가지며 이 값은 컬렉션 내에서 고유하게 식별된다.
ObjectId
ObjectId는 _id의 기본 데이터형 이다. 여러 장비에 걸쳐 전역적으로 고유하게 생성하기 쉽게 설계됐다. 자동 증가 기본키 처럼 전통적인 것을 사용하지 않는 이유는 몽고DB의 분산 특성 때문이다. 자동증가키는 키를 동기화하는 작업이 어렵고 시간이 걸린다. 몽고DB의 이러한 방식은 분산데이터베이스로 설계되어서 샤딩된 환경에서 고유 식별자를 생성하는 것이 매우 중요했다.
ObjectId 12바이트는 타임스탬프 + 랜덤 +카운터(랜덤시작값)을 이용해 생성된다.
첫 4바이트 : 타임스탬프
다음 5바이트: 랜덤값
최종 3바이트: 랜덤값으로 시작하는 카운터
ObjectId의 앞 9바이트는 1초 동안 여러 장비와 프로세스에 걸쳐 유일성을 보장한다. 마지막 3바이트는 단순히 증분하는 숫자로 1초 내 단일 프로세스의 유일성을 보장한다. 고유한 ObjectId는 프로세스당 1초에 1677만 7216개까지 생성된다
_id 자동생성
도큐먼트 입력시 _id키를 명시하지 않으면 입력된 도큐먼트에 키가 자동으로 추가된다.
2.7 몽고DB 셸 사용
사용자 시스템에서 연결 할 수 있는 어떤 몽고DB인스턴스든 셸을 연결할 수 잇다.
help를 입력하면 셸에 내장된 도움말을 볼 수 있다.
데이터베이스 수준의 도움말은 db.help(), 컬렉션 수준의 도움말은 db.컬렉션.help()로 확인한다.
자바스크립트 파일을 셸로 전달해 실행할 수 있다. 단순히 명령행에 스크립트만 넘기면된다.
출처
'DB > MongoDB' 카테고리의 다른 글
[몽고DB 완벽 가이드 3판] 도큐먼트 생성, 갱신, 삭제 (0) | 2022.08.29 |
---|---|
[몽고DB 완벽 가이드 3판] 몽고 DB 소개 (0) | 2022.08.23 |
- Total
- Today
- Yesterday
- update set multi
- multiple row update
- vue.js
- 슬랙봇
- 뱅크샐러드 유전자
- SpringBoot
- 다중 업데이트
- 뱅크샐러드
- 그레이들
- 업데이트 쿼리
- 이것이 자바다
- MSSQL
- visual studio code
- 뱅셀 유전자
- gradle
- update query multi row
- 슬랙
- springboot https
- update query set multiple
- spring-boot-starter-data-redis
- 이펙티브자바
- update query
- update set multiple
- 싱글턴
- update query mutiple row
- 슬랙 /
- java
- effectivejava
- Slack
- 몽고DB 완벽가이드
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |