인덱스 속성
인덱스 필드가 NULL 이 아닌 경우나 지정된 조건을 만족하는 경우에만 인덱스에 추가할 수 있다.
TTL 인덱스도 제공한다.
프라이머리 키와 세컨드리 인덱스
MongoDB 프라이머리 키 필드는 사용자가 필드의 이름을 결정할 수 없다.
프라이머리 키 필드는 무조건 _id 라는 이름으로 도큐먼트에 저장되어야 한다.
그렇지 않으면 MongoDB 가 자동으로 _id 라는 이름의 필드를 생성해서 추가한다.
컬렉션마다 단 하나의 프라이머리 키만 가질 수 있고, 그 외의 인덱스는 모두 세컨드리 인덱스라고 한다.
프라이머리 키는 반드시 유일한 값을 가져야 하므로 유니크 인덱스를 생성할 수 없는 해시 인덱스는 프라이머리 키로 사용할 수 없다.
또한 하나의 샤드에서는 중복 값에 대한 체크를 MongoDB 가 해주지만, 샤딩 된 경우 샤드간 프라이머리 키 값의 중복체크를 응용프로그램에서 처리해야 한다.
프라이머리 키는 _id 필드로 고정되어 있어 컴파운드 인덱스를 프라이머리 키로 선정할 수 없다.
그러나 여러 필드를 묶어서 프라이머리 키로 설정할 수는 있다.
이런 경우는 서브 도큐먼트를 _id 필드에 저장하는 방법을 선택할 수 있다.
서브 도큐먼트를 인덱스 키로 사용하는 경우에는 서브 도큐먼트의 필드 개수와 이름 값까지 같아야 한다.
유니크 인덱스
테이블이나 인덱스에 같은 값을 2개 이상 저장할 수 없음을 의미하는데, MongoDB 에서는 인덱스 없이 유니크 제약을 설정하는 방법이 ㅇ벗다.
하지만 유니크 인덱스라고 해서 NULL 값이 제한되지는 않고 프라이머리 키는 기본적으로 유니크 속성이 부여된다.
MongoDB 의 유니크 인덱스는 NULL 이나 존재하지 않는 값을 같은 값으로 취급하기 때문에 하나 이상의 도큐먼트가 NULL 일 수 없다.
유니크 인덱스는 도큐먼트 간의 중복된 값은 체크하지만, 하나의 도큐먼트내에서 중복된 값을 체크하지는 않는다.
샤딩을 적용하지 않는 MongoDB 는 아무 필드나 선택해서 유니크 인덱스를 생성할 수 있다.
하지만 샤딩을 적용한 경우에는 샤드키를 선행 필드로 가지는 인덱스에서만 유니크 인덱스를 생성할 수 있다.
Partial 인덱스와 Sparse 인덱스
MongoDB 에서 NULL 값을 가지는 필드에 대해 인덱싱할것인지 선택할 수 있는 Sparse 인덱스와
특정 조건에 따라 인덱싱하는 Partial 인덱스 기능을 제공한다.
Sparse 인덱스는 도큐먼트에 인덱스 대상 필드를 명시한 경우에만 인덱스에 키 엔트리를 저장한다.
필드의 값이 NULL 이라 하더라도 필드가 명시되어 있으면 인덱싱 대상이 된다.
또 컴파운드 인덱스인 경우에는 인덱스를 구성하는 필드 중 하나라도 명시하면 인덱싱 대상이 된다.
즉 컴파운드 인덱스를 구성하는 모든 필드가 누락된 경우에만 인덱싱이 제외된다.
만약 컬렉션의 많은 도큐먼트가 특정 필드를 가지지 않는데, 이 필드를 가지는 도큐먼트만 검색을 실행해야 하는 경우 Sparse 가 도움이 될 것이다.
Sparse 인덱스에서 한가지 주의해야 할 사항은 인덱스 필드가 없는 경우를 조회해야 하는 쿼리는 Sparse 인덱스를 사용하지 못한다는 것이다.
다음은 필드의 값이 NULL 인 경우를 검색하는 쿼리다. 이는 MongoDB 에서 존재하지 않는 필드의 비교와 NULL 비교가 상황에 따라 다르게 때로는 같게 취급되는 것을 확인한다.
3.2 버전부터 Sparse 인덱스보다 다양한 기능을 활용할 수 있는 Partial 인덱스 기능이 추가되었다.
Partial 인덱스가 나오고 Sparse 인덱스 기능을 사용할 필요가 없어졌는데,
사용자가 인덱싱을 수행할 도큐먼트를 선택할 수 있고, 조건에 일치하는 도큐먼트에 대해서만 인덱스를 관리하므로 조건부 인덱스라고 한다.
인덱스 생성 시 partialFilterExpression 옵션을 이용해서 생성한다.
이 조건에 사용할 수 있는 연산자는 일반적으로 아래와 같다.
- 일치 표현식 $eq
- 필드가 존재하는 경우 $exists : true
- 크다 또는 작다 비교 표현식 $gt, $gte, $lt, $lte
- 필드 값의 데이터 타입 비교 표현식 $type
- 위 조건을 AND 로 결합하는 표신식 $and
sparse 인덱스는 인덱싱 대상 필드의 존재 여부에 대해서만 선택할 수 있지만,
Partial 인덱스는 인덱스 대상 필드와 무관한 필드에 대한 표현식도 조건으로 선택할 수 있다.
Partial 인덱스도 인덱스를 커버할 수 없는 조건의 쿼리는 인덱스를 사용할 수 없다.
Partial 인덱스를 사용하려면 쿼리의 조건에 인덱스의 생성 조건과 일치 또는 부분 범위의 조건을 명시해야만 한다.
Partial , Sparse 인덱스 모두 유니크 인덱스로 생성하면 조건에 만족해서 인덱싱되는 키 값에 대해서만 유니크 제약 사항이 적용된다.
Partial 인덱스도 결과가 불완전해질수 있는 경우 Parital 인덱스를 활용하지 않는다.
다만 사용자가 쿼리 힌트를 주면 불완전한 결과라고 하더라도 인덱스를 이용해서 처리한다.
TTL 인덱스
컬렉션의 도큐먼트가 언제까지 유효한지를 판단하여 더이상 유효하지 않은 도큐먼트는 자동으로 삭제되게 하는 기능의 인덱스이다.
내부적으로 TTL Monitor 라는 쓰레드가 지정된 시간 간격(기본값 1분)으로 1회씩 깨어나 지정된 시간보다 오래된 도큐먼트를 찾아 제거한다.
실제 TTL 인덱스는 쿼리의 검색 성능 향상을 위한 인덱스가 아니라 Monitor 쓰레드가 삭제할 도큐먼트를 찾기 위한 인덱스이다.
인덱스 생성 시 expireAfterSeconds 속성을 설정하면 된다.
TTL Monitor 쓰레드의 삭제 주기 변경
ttlMonitorSleepSecs 파라미터 값을 조정한다.
TTL Monitor 의 로그 확인
TTL Monitor 쓰레드가 깨어나 작업하는 내용은 기본적으로 MongoDB 서버의 로그에 기록되지 않는다.
그런데 많은 도큐먼트를 삭제하거나 인덱스를 많이 가진 컬렉션에 대해 도큐먼트를 삭제하는 경우 서버 부하가 높아질 수도 있다.
만약 서버 부하가 주기적으로 높아진다면 TTL Monitor 쓰레드의 도큐먼트 삭제를 의심할 수 있는데, 이 때는 Log 를 활성화 해 원인이 TTL 때문인지 확인이 가능하다.
TTLMonitor 라는 서두로 기록된다.
로그의 내용에는 언제 쓰레드가 깨어나 얼마나 많은 도큐먼트를 삭제했는지 출력된다.
이 차이를 계산하면 삭제하는데 걸린 시간을 확인할 수 있다.
그리고 서버 구동 후 몇번이나 실행되었고 얼마나 많은 도큐먼트를 삭제했는지는 db.serverStatus() 결과로 확인할 수 있다.
TTL Monitor 쓰레드 정지 및 시작
쓰레드를 멈추는 방법은 2가지가 있는데, 시작 옵션을 이용해 서버가 시작될 때부터 비활성화 하는 방법이고
다른 하나는 실행중인 서버의 TTL Montior 를 동적으로 중지시키는 방법이다.
ttlMonitorEnabled 로 설정이 가능하다.
TTL 인덱스와 Partial 인덱스
TTL 인덱스 또한 다른 인덱스처럼 Partial 인덱스로 생성할 수 있다.
TTL 인덱스와 복제
TTL 인덱스를 이용해서 데이터를 삭제하는 TTL Monitor 쓰레드는 프라이머리와 세컨드리 멤버 모두 실행되지만
실제 TTL Monitor 쓰레드가 도큐먼트를 삭제하는 작업은 레플리카 셋의 프라이머리 멤버에서만 실행된다.
TTL Monitor 쓰레드가 도큐먼트를 삭제하면 OpLog 에 기록되고, OpLog 를 세컨드리 멤버가 읽어 자신도 동일하게 삭제한다.
TTL 인덱스의 주의 사항
TTL 인덱스로 데이터를 삭제하는 작업은 주로 오래된 데이터가 삭제될 가능성이 높은데,
디스크를 읽어야만 처리할 수 있는 경우가 많다.
그런데 그 컬렉션에 있는 모든 인덱스에 키 엔트리를 삭제해야 하므로 많은 디스크 읽기를 유발하게 된다.
TTL 인덱스는 반드시 Date 타입의 단일 필드로만 인덱스를 생성할 수 있으며, 여러 필드를 묶어서 컴파운드 인덱스를 생성할 수 없다.
또한 타임스탬프 값을 내장하고 있는 _id 필드에 대해서도 TTL 인덱스를 생성할 수 없다.
인덱스 콜레이션 (대소문자 구분)
3.2 버전 대소문자 검색
3.2 버전까지 기본적으로 대소문자를 구분하기 때문에 모두 소문자로 통일한 문자열을 별도로 지정하곤 했다.
3.4 버전부터 컬렉션과 인덱스에 대해 콜레이션을 지정할 수 있게 되었다.
콜레이션과 인덱스 사용
콜레이션은 문자열의 정렬과 비교 규칙을 결정한다.
인덱스 생성 시 특정 콜레이션을 지정하면 새로 생성하지 않는 이상 다른 콜레이션으로 변경이 불가하다.
또 다른 콜레이션을 이용해 조회하면 인덱스를 이용하지 못한다.
외래 키
외래 키에 대한 제약 기능을 지원하지 않는다.
'Database > MongoDB' 카테고리의 다른 글
[MongoDB] 데이터 모델링 (1) | 2024.09.19 |
---|---|
[MongoDB] 잠금과 트랜잭션(2) (0) | 2024.09.09 |
[MongoDB] 잠금과 트랜잭션(1) (0) | 2024.08.09 |
[MongoDB] 인덱스(2) (0) | 2024.08.02 |
[MongoDB] 인덱스(1) (0) | 2024.07.26 |