늦은 새벽 시간즈음 아래 내용이 공부가 하고 싶어 작성하게 되었다. 

mongoDB Collection TTL

몽고 TTL 은 Time-To-Live 인덱스 즉, 특정 시간이 지나면 자동으로 데이터를 삭제하도록 설정하는 기능이다. 이걸 사용하는 가장 큰 목적은 데이터가 계속 쌓이는것을 방지하기 위함이다. 당연하겠지만 디비에 불필요한 데이터가 많이 쌓이면 쿼리의 성능이 떨어지게 된다. 

그러면 TTL 인덱스를 잡을 때 고려해야할 점은 무엇일까? 몽고 디비에서 제공하는 특별한 데이터 유형으로 BSON 날짜 유형을 사용해야 한다. 

예를들면, ISODate 함수 같은것들이다. 근데 이거까지 신경 안써도 될듯 하다. 왜냐하면 프로그래밍 언어에서 몽고 DB Driver 에 해당하는 날짜 유형을 BSON으로 자동으로 변환하기 때문에

쓰다 보니 하나 궁금한것이 생겼다. TTL 은 단일 필드에만 적용가능할까? 

답은 

한가지 예시를 들어보면 로그 컬렉션을 하나 만들었다고 해보자. 

생성 시간을 나타내는 created_at 필드 랑 업데이트 시간을 나타내는 last_updated 필드가 존재할 때 

각 필드에 따라 Document 가 삭제될 날짜를 30일, 7일로 지정했다고 가정해보자.

// 'created_at' 필드에 대한 TTL 인덱스 생성 (30일)
db.logs.createIndex({ "created_at": 1 }, { expireAfterSeconds: 2592000 });

// 'last_updated' 필드에 대한 TTL 인덱스 생성 (7일)
db.logs.createIndex({ "last_updated": 1 }, { expireAfterSeconds: 604800 });

이러면 깔끔하게 각 필드에 대한 TTL 인덱스를 지정할 수 있다. 

한가지 착각하지 말아야 할것은 이렇게 구성된 인덱스는 멀티 인덱스가 아니다. 단일 필드 인덱스로 간주된다. 

멀티 인덱스는 하나의 인덱스가 여러 필드에 적용되는것을 의미한다. TTL 인덱스는 하나의 필드에만 적용된다. 

그러면 단점은 없을까? 생각해볼 수 있다. 

당연히 성능이 떨어진다. Write 작업이 늘어날 수록 인덱스가 업데이트가 되어야하기 때문이다. 

인덱스는 그 값이 저장된 문서를 가리키는 참조를 포함하고 있다. 만약에 값이 바뀌는 경우를 생각해보면 이전에 참조를 인덱스 항목에서 제거하고 변경된 값에 대해 인덱스를 추가하게 된다. 

아래 좋은 그림이 있어서 가져왔다. 

인덱스는 특정 필드 또는 필드 집합의 값을 필드 값에 따라 정렬하여 저장한다. 그러니까... 인덱스 페이지가 있고 실제 물리 데이터가 따로 있는것이다. 

https://www.mongodb.com/docs/v5.3/indexes/

이거 굉장히 비효율적인데?  

5.3 부터 제공되는 clustered index를 사용하면 된다. 

clustered index 즉, clustered collection 을 쓰게 되면 _id 인덱스 문서가 함께 _id 값의 순서대로 저장하게 된다. 이 방식이 인덱스와 실제 데이터가 함께 저장되기 때문에 삽입, 업데이트 실제 작업이 보다 효율적으로 이루어질 수 있다

이것도 non-clustered index, clustered index 같이 쓰는 방식이 효과적일것으로 생각된다.