DB의 민족/MongoDB
Chapter 2. 몽고DB 기본
댕구리댕댕구리
2022. 11. 23. 02:24
728x90
반응형
SMALL
- 몽고DB 데이터의 기본 단위는 도큐먼트이며, 이는 관계형 데이터베이스의 행과 유사
- 같은 맥락에서 컬렉션은 동적 스키마가 없는 테이블과 같음
- 단일 인스턴스는 자체적인 컬렉션을 갖는 여러 개의 독립적인 데이터베이스 호스팅
- 모든 도큐먼트는 컬렉션 내에서 고유한 특수키인 '_id'를 보유
- 몽고 DB는 몽고 셸이라는 간단하지만 강력한 도구와 함께 배포
- 몽고 셸은 몽고DB 인스턴스를 관리하고 몽고DB 쿼리 언어로 조작하기 위해 내장 지원을 제공
- 사용자가 다양한 목적으로 자신의 스크립트를 만들고 로드할 수 있는 완전한 기능의 자바스크립트 해석가
1. 도큐먼트
- 'greeting'이라는 키와 연결된 'Hello world!'라는 값
{"greeting" : "Hello, world!"}
- 도큐먼트의 값은 단지 blob형이 아닌, 값은 데이터형이여야함
- "greeting"의 값은 문자열이며 "views"의 값은 정수
{"greeting" : "Hello, world!", "views" : 3}
- 도큐먼트의 키는 문자열이지만, 아래의 예를 제외하면 어떤 UTF-8 문자든 쓸 수 있음
- 키는 \0(null 문자)을 포함하지 않는다. \0은 키의 끝을 나타내는데 사용
- .과$ 문자는 몇 가지 특별한 속성을 가져 특정 상황에서만 사용. 보통 예약어로 취급(부적절 사용시 경고)
- 몽고DB는 데이터형과 대소문자를 구별
- 아래 두 도큐먼트는 서로 다름
{"count" : 5}
{"count" : "5"}
- 아래도 마찬가지
{"count" : 5}
{"Count" : 5}
2. 컬렉션
- 컬렉션은 도큐먼트의 모음
2 - 1. 동적 스키마
- 아래 다음 도큐먼트들을 하나의 컬렉션에 담을 수 있음
{"greeting" : "Hello world!","views" : 3}
{"signoff" : "Good night, and good luck"}
- 다른 구조의 도큐먼트라도 같은 컬렉션에 저장할 수 있지만, 별도의 컬렉션이 필요한 이유
- 같은 컬렉션에 다른 종류의 도큐먼트를 저장하면 개발자와 관리자에게 번거로운 일 발생
- 컬렉션별로 목록을 뽑으면 한 컬렉션 내 특정 데이터형별로 쿼리해서 목록을 뽑을 때보다 훨씬 빠름
- 같은 종류의 데이터를 하나의 컬렉션에 모아두면 데이터 지역성에 좋음
- 인덱스를 만들면 도큐먼트는 특정 구조를 가져야함. 이러한 인덱스는 컬렉션별로 정의하는데, 같은 유형의 도큐먼트를 하나의 컬렉션에 넣음으로써 컬렉션을 효율적으로 인덱싱 가능
2 - 2. 네이밍
- 빈 문자열(" ")은 유효한 컬렉션명이 아님
- \0(null)은 컬렉션 명의 끝을 나타내는 문자이므로 컬렉션 명에 사용 불가능
- system.으로 시작하는 컬렉션명은 시스템 컬렉션에서 사용하는 예약어이므로 사용 불가능
- system.users = 데이터베이스 사용자 정보
- system.namespaces = 데이터베이스 내 모든 컬렉션의 정보
- 사용자가 만든 컬렉션의 이름에 예약어인 $를 포함 불가
- 서브컬렉션
- 네임스페이스에 .(마침표) 문자를 사용해 컬렉션을 체계화
- 예를 들어 블로그 기능이 있는 어플리케이션은 blog.posts / blog.authors 라는 컬렉션을 가지는데 이는 단지 체계화를 위함 / blog 컬렉션이나 자식 컬렉션과는 아무런 관계가 없음
- 데이터를 체계화하는 훌륭한 접근 방법
3. 데이터베이스
- 데이터베이스는 컬렉션과 마찬가지로 이름으로 식별
- 제약조건
- 빈 문자열(" ") 유효한 데이터베이스 이름이 아님
- 데이터베이스 이름은 다음 문자를 포함 불가(\, /, ., ' ', *, <, >, :, |, ?, $, (단일공간), \0(null문자))
- 데이터베이스 이름은 대소문자 구별
- 데이터베이스 이름은 최대 64바이트
- 특별한 의미를 가지는 데이터베이스
- admin
- 인증과 권한 부여 역할
- 일부 관리 작업을 하려면 admin에 대한 접근 권한필요
- local
- 단일 서버에 대한 데이터를 저장
- 복제 셋에서 local은 복제 프로세스에 사용된 데이터 저장
- local 자체는 복사 불가능
- config
- 각 샤드의 정보를 저장
- admin
- 컬렉션을 저장하는 데이터베이스의 이름을 컬렉션명 앞에 붙이면 올바른 컬렉션명인 네임스페이스를 얻음
- 예로 cms 데이터베이스의 blog.posts 컬렉션을 사용할 경우 네임스페이스는 cms.blog.posts
- 네임스페이스의 최대 길이는 120바이트이지만, 실제로는 100바이트 이내가 이상적
4. 몽고DB 시작
- 환경에 맞게 다운로드
- 아래 블로그는 윈도우 버전 기준
[MongoDB] 윈도우 몽고디비 설치 방법
1. 설치파일 다운로드 https://www.mongodb.com/try/download/enterprise MongoDB Enterprise Server Download Download MongoDB Enterprise Server, which provides advanced security and performance options for the most demanding apps. Use for free for devel
joytk.tistory.com
- 사용할 Tool 설치
Thanks for downloading Studio 3T | Studio 3T
Thanks for downloading Studio 3T! You’re seconds away from a better way of working with MongoDB. Your download should begin shortly.
studio3t.com
5. 몽고DB 셸 소개
- 인스턴스와 상호작용하는 자바스크립트 셸 제공
- 셸은 관리 기능이나, 실행 중인 인스턴스를 점검하거나 간단한 기능을 시험하는데 유용
5 -1. 셸 실행
$mongo
x = 200;
x /5;
Math.sin(Math.PI / 2)
출력값 : 1
- 자바스크립트의 함수를 정의하고 호출도 가능
function factorial (n) {
if (n <=1) return 1;
return n*factrial(n-1);
}
factorial(5);
출력값 : 120
5 - 2. 몽고DB 클라이언트
db;
출력값 : test(각자의 db 이름이 출력)
- 중요한 데이터베이스 선택
use viseo;
db;
5 - 3. 셸 기본 작업
생성
- 셸의 기본 작업인 생성, 읽기, 갱신, 삭제는 CRUD로 정리
movie = {"title" : "Star Wars : Episode IV - A New Hope",
"director" : "George Lucas",
"year" : 1977};
- insertOne 함수는 컬렉션에 도큐먼트를 추가
db.movies.insertOne(movie);
- 영화가 데이터베이스에 저장. 컬렉션에 find를 호출해서 확인
db.movies.find().pretty();
- "_id" 키가 추가됐고 다른 키/값 쌍들은 입력한 대로 저장
읽기
- find / findOne은 컬렉션을 쿼리하는데 사용
- 컬렉션에서 단일 도큐먼트를 읽으려면 findOne 사용
db.movies.findOne()
- find / findOne은 쿼리 도큐먼트 형태로 조건 전달도 가능 ㅡ> 따라서 쿼리에서 일치하는 도큐먼트 결과를 제한
- 셸은 find와 일치하는 도큐먼트를 20개까지 자동으로 출력(그 이상도 가능)
갱신
- 게시물 갱신에서는 updateOne을 사용
- updateOne의 매개변수는 최소 2개
- 수정할 도큐먼트를 찾는 기준
- 갱신 작업을 설명하는 도큐먼트
- 갱신하려면 갱신 연산자 set을 이용
db.movies.updateOne({title : "Star Wars : Episode IV - A New Hope"},
{$set : {reviews : []}});
WiteResult({"nMatched" : 1, "nUpserted" : 0, "nModified" : 1})
삭제
- deleteOne과 deleteMany는 도큐먼트를 데이터베이스에서 영구적으로삭제
- 두 함수 모두 필터 도큐먼트로 삭제 조건을 지정
db.movies.deleteOne({title : "Star Wars : Episode IV - A NEW Hope"});
6. 데이터형
6 - 1. 기본 데이터형
- 몽고DB에서 도큐먼트는 자바스크립트 객체(JSON)와 개념적으로 닮음
- JSON의 표현력은 null, 불리언, 숫자 ,문자열, 배열, 객체만 지원
- JSON형은 날짜형이 없어서 날짜 다루는데 어려움이 있음
- 숫자형은 한 가지만 존재
- 부동소수점형과 정수형을 표현하는 방법은 없으며, 32 / 64비트 구별 불가
- 함수나 정규 표현식의 표현 방법 없음
- null
- {"x" : null}
- 불리언
- 참과 거짓 값에 사용
- {"x" : true}
- 숫자
- 셸은 64비트 부동소수점 수를 기본으로 사용
- {"x" : 3.14} / {"x" : 3}
- 4바이트 혹은 8바이트의 부호 정수는 각각 NumberInt / NumberLong 클래스 사용
- {"x" : NumberInt("3")} / {"x" : NumberLong("3")}
- 문자열
- 어떤 UTF-8 문자열이든 문자열형으로 표현
- {"x" : "foober"}
- 날짜
- 1970년 1월 1일부터 시간을 1/1000초 단위로 나타내는 64비트 정수로 날짜를 저장
- {"x" : new Date()}
- 정규 표현식
- 자바스크립트의 정규 표현식 문법을 사용
- {"x" : /foober/i}
- 배열
- 값의 셋이나 리스트를 배열로 표현
- {"x" : ["a","b","c"]}
- 내장 도큐먼트
- 부모 도큐먼트의 값으로 내장된 도큐먼트 전체를 포함
- {"x" : {"foo" : "bar"}}
- 객체 ID
- 도큐먼트용 12바이트 ID
- {"x" : ObjectId()}
- 코드
- {"x" : function() {/*.....*/}}
6 - 2. 날짜
- 새로운 날짜를 생성시에는 Date()가 아닌 new Date() 사용
- 함수로 생성자를 호출하면 실제 객체 Date()가 아닌 날짜의 문자열을 반환
- 따라서 항상 Date() 생성자 사용시 주의
6 - 3. 배열
- 정렬 연산(리스트, 스택, 큐)과 비정렬 연산(셋)에 호환성이 있게 사용
- 예시 ㅡ> {"things" : ["pie", 3.14]}
6 - 4. 내장 도큐먼트
- 도큐먼트는 키에 대한 값이 될 수 있는데 이를 내장 도큐먼트
- 예를 들어 사람의 정보를 나타내는 도큐먼트에 주소를 저장하려면 정보를 'address' 내장 도큐먼트로 중첩
- "address"에서 키에 대한 값은 "street","city","state"의 키/값 쌍을 갖는 내장 도큐먼트
{
"name" : "John Doe",
"address" : {
"street" : "123 Park Street",
"city" : "Anytown",
"state" : "NY"
}
}
6 - 5. _id 와 ObjectId
- _id는 하나의 컬렉션에서 모든 도큐먼트는 고유하게 가지는 값
- ObjectIds
- "_id"의 기본 데이터형
- 경량으로 설계됐으면서도 여러 장비에 걸쳐 전역적으로 유일한 방법으로 생성 가능
- 기본키가 아닌 ObjectId를 사용하는 이유는 기본키는 전통적이지만 여러 서버에서 자동으로 증가해 동기화 작업이 어렵고 시간이 오래 걸림
- ObjectId는 12 바이트 스토리지를 사용하면 24자리 16진수 문자열 표현 가능 / 바이트당 2자리 사용
- ObjectId 12바이트
-
더보기0(타임스탬프) 1(랜덤) 2(카운터 ㅡ 랜덤 시작 값) 3 4 5 6 7 8 9 10 11
-
- ObjectId의 첫 4바이트는 1970년 1월 1일부터의 시간을 1/1000초 단위로 저장하는 타임스탬프
- 타임스탬프의 속성
- 다음 5바이트와 묶일 때 초 단위의 유일성 제공
- 타임스탬프가 맨 처음에 온 다는 것은 ObjectId가 대략 입력 순서대로 정렬된다는 의미
- 4바이트에는 각 도큐먼트가 생성된 때마의 잠재적인 타임스탬프 존재
- 타임스탬프의 속성
- ObjectId의 다름 5바이트는 랜덤 값
- 최종 3바이트는 서로 다른 시스템에서 충돌하는 ObjectId들을 생성하지 않도록 랜덤 값으로 시작하는 카운터
- 앞 9바이트는 1초 동안 여러 장비와 프로세스에 컬쳐 유일성을 보장
- 마지막 3 바이트는 단순히 증분하는 숫자로, 1초 내 단일 프로세스의 유일성 보장
- 고유한 ObjectId는 프로세스당 1초에 256**3(1677만 7216)개까지 생성
7. 몽고DB 셸 사용
7 - 1. 셸 활용 팁
help
- DB 수준의 도움말 = db.help() / 컬렉션 수준의 도움말 = db.foo.help()
7 - 2. 셸에서 스크립트 실행하기
- 단순히 명령행에 스크립트를 넘기면 됨
$mongo script1.js script2.js script3.js
- 기본값으로 지정되지 않은 호스트나 포트 mongod에 연결해 사용하는 스크립트 실행
- --quiet는 "MongoDB shell version v4.2.0" 배너를 미출력
$ mongo server-1:30000/foo --quiet script1.js script2.js script3.js
load("script1.js")
- 셸 보조자와 대응하는 자바스크립트 대응법
- use video = db.getSisterDB("video")
- show dbs = db.getMongo().getDBs()
- show collections = db.getCollectionNames()
- connectTo 함수 정의 방법
// defineConnectTo.js
/**
* 데이터 베이스에 연결하고 db를 설정
*/
var connectTo = function(port, dbname) {
if (!port){
port = 27017;
}
if (!dname){
dbname = "test";
}
db = connect("localhost:"+port+"/"+dbname);
return db;
}
typeof connectTo
load('defineConnectTo.js)
typeof connectTo
run("ls", "-l", "/home/myUser/my-scripts/")
7 - 3. mongorc.js 만들기
- 자주 로드되는 스크립트(셸이 시작할 때마다 실행되는) .mongorc.js 파일에 넣을 수 있음
// .mongorc.js
var compliment = ["attractive","intelligent","like Batman"];
var index = Math.floor(Math.random()*3);
print("Hello, you are looking particularly "+compliment[index]+" today!");
- .mongorc.js의 일반적인 용법 중 하나는 '더 위험한' 셸 보조자를 제거
- dropDatabase / deleteIndexes 같은 함수 사용
var no = function(){
print("Not on my watch")';
};
// 데이터베이스 삭제 방지
db.drppDatabase = DB.prototype.dropDatabase = no;
// 컬렉션 삭제 방지
DBCollection.prototype.drop= no;
// 인덱스 삭제 방지
DBCollection.prototype.dropIndexe = no;
// 인덱스 삭제 방지
DBCollection.prototype.dropIndexes = no;
- 코드를 실행하게 되면 오류 메세지가 발생
- 악의적인 사용자로부터 보호하는 기능이 아닌, 의도치않게 키를 잘못 눌러 명령을 실행했을 때 도움
- 셸을 시작할 때 --norc 옵션을 사용해 .mongorc.js의 로딩을 비활성화
7 - 4. 프롬포트 커스터마이징하기
- 몇 분이 걸리는 쿼리를 실행할때, 마지막 작업이 완료된 시각을 출력하는 프롬프트 생성
prompt = function() {
return (new Date())+ " > ";
};
- 현재 사용하는 데이터베이스를 보여주는 프롬프트 생성
prompt = function() {
if (typeof db == 'undefined'){
return '(nodb)> ';
}
// 마지막 db 연산 확인
try {
db.runCommand({getLastError:1});
}
catch(e) {
print(e)
}
return db+ "> ";
};
7 - 5. 복잡한 변수 정하기
EDITOR = "/usr/bin/emacs"
- edit 변수명 형식으로 변수를 편집
var wap = db.books.findOne({title : "War and Peace"});
edit wap
7 - 6. 불편한 컬렉션명
> db.version
[Function: version] AsyncFunction {
apiVersions: [ 0, 0 ],
returnsPromise: true,
serverVersions: [ '0.0.0', '999.999.999' ],
topologies: [ 'ReplSet', 'Sharded', 'LoadBalanced', 'Standalone' ],
returnType: { type: 'unknown', attributes: {} },
deprecated: false,
platforms: [ 'Compass', 'Browser', 'CLI' ],
isDirectShellCommand: false,
acceptsRawInput: false,
shellCommandCompleter: undefined,
help: [Function (anonymous)] Help
}
- 컬렉션명이 예약어가 아니거나 유효하지 않은 자바스크립트 속성명이 아니라면 db.collectionName 구문 사용
- foo-bar-baz 나 abc123과 같은 자바스크립트에 유효하지 않은 문자로 컬렉션명을 만들었을 때도 가능
- 자바스크립트는 오직 문자, 숫자, $, _만 가능하며, 숫자로 시작 불가능
> db.getCollection("version")
test.version
- 다른 방법으로는 배열 접근 구문을 사용해 유효하지 않는 속성명을 피할 수 있음
- 자바스크립트에서 x.y = x['y'] 가능 ㅡ> 서브컬렉션이 상수 이름뿐만 아니라 변수를 이용해서도 접근이 가능함을 의미
var collection = ["posts","comments","authors"]
for (var i in collection){
... print(db.blog[collection[i]]);
}
- for 루프 대신에 blog만 사용해서도 가능
print(db.blog.posts);print(db.blog.comments);print(db.blog.authors);
- test.blog.posts가 아닌 test.blog.i로 해석될 수 있는 db.blog.i는 사용 불가
- i가 변수로 해석되려면 db.blog[i]구문 사
var name ="@&#!"
db[name].find()
몽고DB 완벽 가이드 - YES24
NoSQL의 진수 몽고DB 개발부터 관리까지몽고DB 입문자를 위한 기초부터 실제 배포에 적용할 수 있는 실용적이고 깊이 있는 내용까지 담았다. 개정 3판에서는 성능이 강화된 몽고DB 최신 버전을 반
www.yes24.com
728x90
반응형
LIST