1. MongoDB완벽 가이드- 4장 쿼리하기발표 : 유유(유장혁)

2. 순서찾기 소개쿼리 조건형 특정 쿼리$where 쿼리커서커서 내부 작동


3. 찾기 소개


4. Find 메소드db.c.find( )컬렉션 C 안의 모든 문서를 반환find 메소드에 쿼리 문서가 없다면 빈 쿼리 문서 {}로 인식빈 쿼리 문서(즉,{})는 컬렉션 내 모든 것과 일치한다검색 제한키 /값 쌍db.users.find( { "age" : 27 } )조건1 AND 조건2 AND . . . AND 조건N


5. 반환 받을 키 지정하기모든 키/값 정보가 필요한 건 아닐 경우db.users.find ( { }, ( " username" : 1, "email" : 1 } )“_id" 키는 특별히 지정하지 않아도 항상 반환특정 키 /값 쌍을 제외db.users.find( { }, { “username" : 0 } )


6. 제약 사항쿼리의 값은 데이터베이스 관점에서는 반드시 상수여야 한다 (코드 내에서는 일반 변수여도 상관 없다)문서 내 다른 키의 값을 참조할 수 없음> db.stock.find( { "in_stock" : "this.num_sold" } ) / / 작동하지 않는다.


7. 쿼리 조건


8. 쿼리 조건절비교 연산자"$lt" - <"$lte" - <="$gt" - >"$gte" - >=> db.users.find ( { " age " : { " $gte " 18, " $lte " : 30 } } )"$ne" - != ‘not equal'


9. OR 쿼리"$in“ 반대 "$nin"하나의 키 에 대해 다양한 값들과 비교하는 쿼리에 사용> db.raffle.find( { "ticket_no" : { "$in“ : [ 725, 542, 390 ] } } )다른 데이터형도가능> db.users.find( { "user_id" : { "$in" : [ 12345, "joe" ] } )"$or" 조금 더 일반적인 것이며 여러 키에 대해 주어진 값을 비교하는 쿼리에 사용가능한 조건들의 배열> db.raffle.find( { "$or" : [ { "ticket_no" : 725 }, { “winner " : true } ] } )> db.raffle.find ( { "$or " : [ { "ticket_no" : { "$in" : [ 725, 542, 390] } } , { "winner" : true } ] } )


10. $not"$not“메타 조건절특히 정규표현식과 함께 사용해 주어진 패턴과 일치하지 않는 문서를 찾을 때 유용하다결과와 일치하지 않는 문서내 값> db.users.find ( { "id_num" : { "$not" : { "$mod " : [ 5, 1 ] } } } )


11. 조건절의 법칙접두사 $를 가진 키들의 위치가 다르다조회 쿼리에서 "$lt"는 내부 문서에서 사용하고 갱신 쿼리에서 “$inc"는 외부 문서를 위한 키다조건절을 내부 문서의 키로,제한자는 외부 문서의 키로 사용한다.하나의 키에 여러 조건을 걸 수 있다.하나의 키에 여러 조건절을 사용할 수 있다.하나의 키에 여러 갱신 제한자는사용할 수 없다


12. 형 특정 쿼리


13. nullnull은 자신과 일치하는 것 뿐만 아니라 “존재하지 않는” 것과도 일치만약 값이 null인 키 만 찾고 싶다면,"$exists" 조건절을 사용해 키 가 null인 키의 존재 여부를 확인할 수 있다.> db.c.Find ( { "z" : { "$in" : [ null ], "$exists" : true } } )


14. 정규표현식유연하게 매칭되는 문자열을 찾아 낼 때 / 대소문자 구별 없이 찾을 수 있다> db.users.find( { "name" : / joe/ i } )정규표현식의 플래그 (i)는 사용할 수 있으나 꼭 필요한 것은 아니다.> db.users.find ( { "name" : / joey? / i } )PCRE = Perl Compatible Regular Expression = Perl 호환 정규표현식/joey?/prefixregular-expression = 프리픽스정규표현식/^joey/해당하는 쿼리를 더 빠르게 실행


15. 배열에 쿼리하기배열의 각 요소는 대개 전체 키의 값인 것처럼 다룰 수 있다전체 배열 모두와 정확하게 일치하는 것을 쿼리할 수도 있다.배열 내 특정 요소를 쿼리하려면,key.index구문을 사용하여 순서를 지정할 수 있다.배열은 항상 0에서 시작> db. food.find( { "fruit.2" : "peach"})


16. $all 연산자배열 내 하나 이상의 요소가 일치하는 배열을 찾을 때> db. food.find ( { “fruit” : { $all : [ "apple“, "banana" ] } } )$size 연산자주어진 크기의 배열을 반환> db.food.find( { "fruit“ : {"$size" : 3}})"$size'’는 다른 $ 조건절과결합하여 사용할 수 없지만, 문서에 ”size”키를 추가하면 이런 쿼리를 처리할 수 있다값의 증가는 매우 빠르게 이루어지므로 성능에 대해서는 크게 걱정할 필요가 없다> db.food.find( { "size“ : { "$gt“ : 3 } } )


17. $slice 연산자배열 요소의 부분 집합을 반환오프셋과 요소 개수를 사용하여 원하는 범위에 있는 결과를 반환> db. blog. posts. findOne ( criteria,{ "comments" : { "$slice" : -10 } } ) // 끝에서 10> db.blog. posts. findOne ( criteria,{ "comments“ : { "$slice" : [ 23,10] } } ) // 24 ~ 34특별히 명시하지 않는 한,"$slice" 연산자는 문서 내 모든 키를 반환한다키 명시자에 직접 지정하지 않아도 "title"과 "content" 키 모두를 반환한다.


18. 내장 문서에 쿼리하기전체 문서 혹은 내장 문서 내 각 키/값 쌍을 대상가능하다면 내장 문서를 쿼리할때는 특정 키나 키들을 가지고 쿼리하는 방법이 좋다전체 문서를 대상으로 ‘정확한 일치’를 찾는 방법이 아니기 때문에 스키마가 변경되더라도 모든 쿼리 가 정상적으로 작동된다점 표기 법을 사용 // URL 형식> db. people. find ( { "name. first" : "Joe", "name.last“ : "Schmoe" } )점을 포함할 수 있고 이는 ‘내장 문서 내 항목에 접근’할 수 있다는 뜻이다URL을 키로 삼을 때 잦은 문제를 야기시킨다


19. "$elemMatch“모든 키를 지정하지 않고도 조건을 정확하게 묶을 때 사용배열 내에서 하나의 내장 문서를 찾기 위한 조건을 부분적으로 지정할 수 있도록 해준다조건의 ‘그룹핑’을 지원한다내장 문서 에 하나 이상의 키에 대 해 조건과 일치 여부를 확인할 때만 필요하다> db. blog.find ( { "comments“ : { "$elemMatch“ : { "author" : "joe" , "score" : ( "$gte" : 5 } } } } )


20. $where 쿼리


21. 표현할 수 없는 쿼리들은 임의의 자바스크립트를 쿼리의 일부분으로 실행일반 쿼리보다 훨씬 느리다각 문서는 BSON에서 자바스크립트 객체로 변환해야 하기 때문쓸 수 있는 색 인도 없다두 키 의 값을 비교하는 쿼리> db. foo. find ( { "$where“ : function ( ) { ... };문자열> db. foo.find( { "$where" : "this. x + this. Y == 10" } )> db. foo. find ( { "$where" : "function( ) { return this. x + this. y == 10; } " } )


22. 커서

23. 쉘에서커서를 생성하기 위해서는 문서들을 컬렉션에 집어넣고,그에 대해 쿼리를 수행하고, 결과를 지역 변수”var”로 선언된 변수들은 지역 변수이다)에 할당> var cursor db.collection.find( ) ;한 번에 하나씩 결과를 볼 수 있다쉘에서실제 프로그래밍을 하기에는 적합하지 않다.커서의 next 메소드를사용> while ( cursor.hasNext( ) ) { obj cursor.next( ); }반복자iterator 인터페이스를 구현하고 있어서 forEach반복문에사용> cursor. forEach ( function( x ) { } );


24. 쉘은 데이터베이스에 바로 쿼리하지않는다커서 객 체 상의 거의 모든 메소드는 커 서 자체를 반환하기 때문에 이 메소드들을 어 떤 순서로도 이 어 쓸 수 있다이 시 점 에서 쿼 리 는 아직 수행되지 않았다. 쿼 리를 만들기 만 했을 뿐이다> cursor. hasNext( )쉘은next 나hasNext메 소드 호출 시 서버 까지 왕복 횟수를 줄이기위해서한 번에 처음 100개 또는 4MB 크기의 결과(둘 중 작은 것)를 가지고 온다


25. 제한, 건너뛰기, 정렬제한limit 함수> db.c.find().limit(3)건너뛰기> db.c.find().skip(3)정렬객체를 매개 변수로 받는다키/값 쌍의 셋이고,키는 키의 이름이고, 값은 정 렬방향이다정렬 방향은 1(오름치순)이 거 나 -1(내림차순)> db.c.find().sort({ username : 1, age : -1 } )조합> db.stock.find( { "desc" : "mp3" } ). limit(50).skip(50).sort ( { "price“ : -1 } )


26. 비교 순서데 이 터 형을 비교하는 위계 구조최소값헝null형숫자형(정수형, 롱형, 더블형)문자열형객체 문서형배열형이진 데이터형객체 ID형불리언형날짜형타임스탬프형Timestamp정규표현식형최대값형


27. 많은 수의 skip 피하기많은 수의 결과에서 skip은 느릴 수 있다문서 자체에 조건을 만들어두거나, 또는 바로 전 쿼리의 결과를 가지고 다음 쿼리를 계산할Skip을 사용하지 않고 페이지 나누기Limit 를 사용하여 첫 번째 페이지를 반환하고 다음 페이지들은 첫 페이지부터 오프셋을 주어 반환하는 것이다> var page1 = db.foo.find( criteria ).limit (100)> var page2 = db.foo.find ( criteria ).skip (100). limit(100 )


28. 문서 랜덤 찾기순진한(그리고 느린) 방법은 문서의 전체 개수를 세고 find를 한 후,0부터 컬렉션의 크기 사이의 랜덤으로 정 해진 숫자만큼 건너뛰는 것이다.결국 컬렉션에서 랜덤으로 요소를 봐야 한다면 훨씬 효율적 인 방법 문서를 입력 할 때 랜덤 키를 별도로 추가하는 것이다skip을 사용하는 대신에 랜덤 수를 계산해 사용할수있다랜덤 키가 색인되었는지 명확히 해야 한다


29. 고급 쿼리 옵션일반형 쿼리형태> var cursor = db.foo.find ( { "foo" : "bar" } )감싼형 쿼리형태> var cursor = db.foo. find({ "foo" : "bar"}) .sort ({"x" : 1})$maxscan : 정수형쿼리에서 살펴볼 문서의 최대 숫자를 지정$min : 문서형쿼리의 시작 조건$max : 문서형쿼리의 끝 조건$hint : 문서형서버에 쿼 리 에 서 사용할 색 인을 일러준다$explain : 불리언형쿼리가 어떻게 수행될 것인지에 대한 설명 (사용된 인텍스, 결과의 개수, 수행 시간)$snapshot : 불리언형쿼리를 수행한 시점 후의 일관된 스냅샷을 유지할 것을 지정


30. 커서 내부 작동


31. 커서클라이언트가 보는 커서클라이언트 커서 가 나타내는 데이터베이스가 보호 커서커서는 메모리와 자원을 점유한다커서를 종료하는 (그리고 이후 작업도 정리함) 조건커서는 조건과 일치하는 결과를 모두 살펴본 후에는 스스로 정리한다커서가 클라이언트 측에서 유효 영역 비깥으로나갈 경우,드라이버는 데이터베이스에 특별한 메시지를 보내 커서를 종료해도 된다고 알린다시용자가 결과를 아직 다 살펴보지 않았고, 커서가 여전히 유효 영역 내에 있더라도 10분 동안 활동이 없으면 데이터베이스 커서는 자동으로 죽는다 (타임이웃에 의한 종료)타임아웃을 못하게 하는 immortal 이라는 함수커서의 타임아웃을 비활성화했다면 반드시 결과를 모두 살펴보거나 또는 명확히 커서를 종료해야 한다. 그렇지 않으면 커서는 데 이 터 베이스에 계속 남아 자원을 점유할 것이다.


http://www.slideshare.net/niddo/mongo-d-b

'Database > DB Tip' 카테고리의 다른 글

서브 쿼리 종류  (0) 2010.04.02
DB 전문가로 산다는 것 (1)  (1) 2010.01.22

스칼라 서브쿼리 : SELECT 절에 나오는 서브쿼리
인라인 뷰 : From 절 뒤에 오는 서브 쿼리
서브 쿼리 : Where 절 뒤에 오는 서브 쿼리

'Database > DB Tip' 카테고리의 다른 글

몽고 쿼리 응용  (0) 2013.10.08
DB 전문가로 산다는 것 (1)  (1) 2010.01.22

아쉽게도 필자는 프로젝트를 수행하면서 그리고 많은 사이트를 지원하면서 기술을 리드(Lead)하는 전문 DBA의 부재를 절실하게 느꼈었다. 따라서 이 글에서는 많은 사람들이 해보고 싶어 하는 전문 DBA가 무엇인지 그리고 전문 DBA가 수행해야 할 일에는 어떤 것들이 있는지를 함께 이야기해 보자. 

전문 DBA는 반드시 필요하지만 현실은 전문 DBA를 육성하지 않고 있다. 그러다 보니 많은 프로젝트에서 어려움을 경험하게 되고 이제는 많은 곳에서 DBA의 필요성이 부각되고 있는 것 또한 현실이다. 그렇다면 전문 DBA는 무엇을 수행하는 업무인가? 

- 데이터베이스 엔진 관리
- 데이터베이스 모니터링
- 오브젝트 관리
- 데이터베이스 백업
- 데이터베이스 복구
- 데이터베이스 엔진 최적화
- SQL Tuning
- 논리적 모델링 관리
- 물리적 모델링 수행
- 데이터 표준화 수행

위와 같은 업무를 수행하는 것이 일반적인 전문 DBA의 역할일 것이다. 이러한 항목은 데이터베이스를 수행하는 사람마다 조금씩은 다르다. 하지만, 항목이 조금 다르더라도 위의 항목들은 전문 DBA로 성장하기 위해 반드시 필요한 항목임에는 틀림없다. DBA를 희망하는 모든 사람들과 회사의 관리자에게 말하고 싶은 게 있다. IT의 기술을 리드하는 DBA는 하루 아침에 만들어지지 않는다. 10년이라는 시간을 두고 계속 노력하지 않는다면 전문 DBA는 만들어질 수 없다. 회사의 관리자라면 이러한 DBA를 육성하기 위해 노력해야 할 것이다. 

데이터베이스 엔진은 내가 책임진다 

데이터베이스 시스템을 구축한다면 가장 기본이 되는 것이 당연히 데이터베이스를 설치하는 작업이다. 데이터베이스의 설치 또한 DBA의 가장 기본적인 업무가 될 것이다. 그렇다면 데이터베이스만을 설치하며 DBA가 해야 할 일은 모두 끝난 것인가? 우리가 PC에 소프트웨어를 설치하면 보통의 경우에는 사용만 할 뿐이지만 데이터베이스 엔진만을 설치하고 관리 없이 사용만 한다면 얼마 지나지 않아 엄청난 재앙이 발생할 것이다. 그렇다면 데이터베이스 엔진 관리를 위해 무엇을 해야 하는지 확인해 보자.

 - 데이터베이스 버그 관리 : 사용 중인 데이터베이스 버전에서 발생하는 버그를 관리해 해당 버그에 대한 해결 방법을 관리한다.
- 데이터베이스 버전 및 패치 관리 : 해당 버전을 통해 원하는 서비스를 수행할 수 있는지 또는 다른 기능을 위해 데이터베이스 버전을 업그레이드해야 하는지를 관리 및 결정한다. 또한, 버전과 다르게 관리되는 버그 및 보안 등의 각종 패치를 관리해 데이터베이스의 안정성을 보장해야 한다.
- 데이터베이스 엔진 백업 : 데이터베이스 엔진은 실제 데이터만큼 자주 백업을 수행할 필요는 없지만 엔진 자체의 문제에 의해 재설치를 수행해야 할 경우를 대비해 엔진 백업 본을 준비해야 한다. 

데이터베이스 엔진과 관련되어 DBA가 수행해야 할 업무는 위와 같다. 위에서 언급한 하나하나의 항목은 어려운 업무는 아니다. 어떻게 보면 단순한 업무 성격을 가진다. 하지만 데이터베이스를 운영함에 있어서 매우 중요한 업무임에는 틀림없다. 

데이터베이스 상태를 점검하라 

DBA는 이와 같은 엔진 관리의 업무뿐만 아니라 데이터베이스의 상태를 점검하는 모니터링의 업무를 가지고 있다. 그렇다면 과연 어떤 항목을 모니터링해야 하는가? 

- 오브젝트의 상태
- 메모리 상태
- 디스크 상태
- 에러 상태

크게 보면 위와 같이 세 가지 항목에 대해 모니터링을 수행해야 할 것이다. 오브젝트의 상태는 인덱스 중 사용하지 못하는 인덱스가 존재하는지 또는 테이블 중 공간을 할당할 수 없는 테이블이 존재하는지 등에 대한 주기적인 모니터링이 필요할 것이다. 메모리 상태는 메모리의 크기가 최적화되어 있는지 부족하지는 않는지에 대한 모니터링이 필요하며 메모리 관련 Waiting 또한 관심 있게 확인해야 할 것이다. 디스크 상태는 디스크 I/O의 상태를 확인하는 부분에 중점을 둬야 할 것이다. 에러 상태는 로그 등을 확인해 에러에 대한 지원을 해야 할 것이다. 이와 같이 데이터베이스의 상태를 항상 모니터링해야 한다. 

다양한 백업 방법을 숙지해라 

데이터베이스 시스템도 다른 시스템 또는 우리가 사용하는 PC와 마찬가지로 언제든지 문제가 발생할 수 있고 그에 따라 해당 시스템에 보관되어 있는 데이터를 분실할 수 있다. 따라서 데이터 또는 데이터베이스에 문제가 발생했을 경우를 대비해 기존에 데이터를 특정한 장소에 복사해 두어야 한다. 특히 데이터베이스 시스템은 기업에서 사용하는 매우 중요한 데이터를 다루므로 데이터를 복사하는 전략과 전술이 요구된다. 데이터베이스에서 사용할 수 있는 백업은 크게 다음의 두 가지로 구분된다. 

 - 물리적 백업(Logical Backup)
- 논리적 백업(Physical Backup)
 이 가운데 물리적 백업은 아래와 같이 두 가지로 구분된다. 

- HOT 백업 : 온라인 중에 데이터베이스의 구성 요소인 컨트롤 파일, 리두로그 파일 및 데이터 파일을 백업으로 지정된 매체로 복사하는 방법
- COLD 백업 : 온라인 상태가 아닌 오프라인 상태에서 구성 요소인 컨트롤 파일, 리두로그 파일 및 데이터 파일을 백업으로 지정된 매체로 복사하는 방법

결국, 두 가지 방법의 차이는 데이터베이스가 사용 중인 온라인에서 백업을 수행하는가 아니면 데이터베이스의 서비스를 정지하고 오프라인에서 백업을 수행하는가의 차이이다. 물론, 이와 같은 차이 외에도 문제가 발생해 복구를 수행할 경우 HOT 백업은 현시점까지 복구가 가능한 아키텍처를 가지고 있지만 COLD 백업은 일반적으로 백업을 수행한 시점까지만 복구가 가능한 방식이다. 이와 같은 복구의 차이는 백업 전략의 엄청난 차이를 발생시키게 된다.

논리적 백업은 보통의 경우 테이블별로 데이터를 백업하는 경우를 의미한다. 따라서 테이블별로 복구를 수행할 수 있으며 백업 본을 이용한 복구 시에는 백업을 수행한 시점까지 복구할 수 있다. 

지금 우리에게 필요한 것은 완벽한 백업 전략

이처럼 DBA 업무에는 백업이라는 중요한 업무가 있으며 백업 업무를 올바르게 수행하기 위해서는 위와 같은 기본 지식을 이해하고 있어야만 완벽한 백업을 수행할 수 있다. 또한, DBA의 중요한 업무는 백업의 전략을 수립하는 것이다. 이와 같은 백업 전략을 수립하기 위해서는 데이터 장애 발생 시 어떤 수준으로 복구를 원하는지를 반드시 고객과 협의해야 할 것이다. 예를 들어, A 테이블이 문제가 발생해 엑세스되지 않을 경우 A 테이블을 복구해야 할지 개발 담당자가 해당 데이터를 가공할 수 있는지 아니면 해당 테이블이 삭제되어도 문제가 없는지 등을 정확히 이해해야 한다. 해당 테이블이 반드시 필요한 테이블이라면 해당 테이블에 대해 논리적 백업을 수행해야 할 것이다. 또한, 논리적 백업은 백업 시점까지만 해당 데이터를 복구할 수 있으므로 이에 대한 고객과의 정확한 협의를 DBA가 주도해야 한다. 

결국, 백업 전략은 DBA가 수립해야 하며 백업 전략을 수립하기 위해서는 고객과 데이터 복구 수준을 정확히 협의해야 한다. 고객의 정확한 요구 사항이 파악되었다면 이에 맞게 물리적 백업과 논리적 백업을 이용한 양방향 백업을 수행한다. 백업 전략 수립 시 또 하나의 고려 사항은 보관 주기이다. 백업 데이터를 얼마동안 보관할지도 백업 전략에 포함되어야 한다. 백업은 DBA의 가장 기본적인 업무 중 하나로, 이는 잘하면 본전이지만 잘못할 경우 큰 문제를 발생시킨다. 이와 같이 가장 기본인 백업 전략을 제대로 수행하지 못한다면 어찌 DBA라고 할 수 있겠는가? 이제부터라도 전문 DBA로 발전하기 위해 기본에 충실해야 할 것이다. 

필자소개
권순용 kwontra@hanmail.net|Data Consulting 업무를 수행하는 ㈜엑시엄의 대표이사이며 DBA로 시작해 SQL 튜닝, 데이터베이스 아키텍처 및 모델링 업무를 주로 수행했다. 데이터베이스 교육에도 많은 관심을 가지고 있으며 저서로는 『Perfect! 오라클 실전 튜닝, 『초보자를 위한 오라클 10g』 및 『INSIDE SQL』이 있다. 또한, 데이터 액세스 최적화에 대한 특허를 출원했다.

출처 : 한국 마이크로 소프트웨어 [2010년 1월호]
제공 : DB포탈사이트 DBguide.net

'Database > DB Tip' 카테고리의 다른 글

몽고 쿼리 응용  (0) 2013.10.08
서브 쿼리 종류  (0) 2010.04.02

+ Recent posts