MongoDB - 고급 인덱싱

안녕하세요, 데이터베이스 열정가 여러분! 오늘 우리는 MongoDB의 흥미로운 고급 인덱싱 세계로 다 함께 뛰어들어 볼 거예요. 프로그래밍에 처음 도전하는 분이라도 걱정 마세요; 저는 각 개념을 단계별로 안내해 드릴 테니까요. 수년 동안 수많은 학생들에게 가르쳐온 경험을 바탕으로 말이죠. 당신의 좋아하는 음료를 한 잔 챙기고, 이 여정을 함께 시작해 보세요!

MongoDB - Advanced Indexing

배열 필드 인덱싱

거대한 도서관을 정리하는 상상해 보세요. 책장이 가득한 책들 속에서 원하는 책을 빠르게 찾는 방법은 무엇일까요? 바로 인덱싱이 그 역할을 합니다. MongoDB에서 배열 필드를 인덱싱하는 것은 여러 저자나 장르를 가진 책들을 위한 특별한 목록을 만드는 것과 같습니다.

기본 배열 인덱싱

간단한 예제로 시작해 보겠습니다. 가정할 때, 우리는 여러 저자를 가진 책들의 컬렉션을 가지고 있습니다.

db.books.insertMany([
{ title: "The Great Adventure", authors: ["John Doe", "Jane Smith"] },
{ title: "Mystery Island", authors: ["Jane Smith"] },
{ title: "Cooking Masterclass", authors: ["Chef Gordon", "Chef Julia"] }
])

authors 배열 필드에 인덱스를 생성하려면 다음과 같이 합니다:

db.books.createIndex({ authors: 1 })

이 인덱스를 사용하면 저자 중 누구든지 빠르게 찾을 수 있습니다. 쿼리를 시도해 보겠습니다:

db.books.find({ authors: "Jane Smith" })

이 쿼리는 "The Great Adventure"와 "Mystery Island"을 효율적으로 반환합니다. 그 이유는 Jane Smith가 두 책의 저자이기 때문입니다.

다중 키 인덱스

우리가 만든 것은 다중 키 인덱스입니다. MongoDB는 배열 필드를 인덱싱할 때 자동으로 이러한 유형의 인덱스를 생성합니다. 이는 각 책의 각 저자에 대한 별도의 목록 항목을 만드는 것과 같습니다.

내장 배열 인덱싱

이제 좀 더 복잡한 상황을 살펴보겠습니다. 책의 장을 인덱싱하고 싶다면 어떻게 할까요?

db.books.insertOne({
title: "Learn MongoDB",
chapters: [
{ number: 1, title: "Introduction", pages: 20 },
{ number: 2, title: "Basic CRUD Operations", pages: 30 },
{ number: 3, title: "Indexing", pages: 25 }
]
})

장의 제목에 인덱스를 생성할 수 있습니다:

db.books.createIndex({ "chapters.title": 1 })

이제 장의 제목으로 책을 빠르게 찾을 수 있습니다:

db.books.find({ "chapters.title": "Indexing" })

서브 문서 필드 인덱싱

서브 문서 인덱싱은 책의 상세 정보를 기반으로 한 목록을 만드는 것과 같습니다. 복잡하고 중첩된 데이터 구조를 가지고 있을 때 매우 유용합니다.

기본 서브 문서 인덱싱

학생들의 주소 정보를 가진 컬렉션을 고려해 보겠습니다:

db.students.insertMany([
{
name: "Alice",
address: { city: "New York", zipcode: "10001" }
},
{
name: "Bob",
address: { city: "Los Angeles", zipcode: "90001" }
}
])

주소 서브 문서의 도시 필드에 인덱스를 생성하려면 다음과 같이 합니다:

db.students.createIndex({ "address.city": 1 })

이제 도시로 학생들을 효율적으로 검색할 수 있습니다:

db.students.find({ "address.city": "New York" })

서브 문서에 대한 복합 인덱스

occasionally search for students by both city and zipcode:

db.students.createIndex({ "address.city": 1, "address.zipcode": 1 })

이 복합 인덱스를 사용하여 다음과 같은 효율적인 쿼리를 수행할 수 있습니다:

db.students.find({ "address.city": "New York", "address.zipcode": "10001" })

중첩 배열 인덱싱

이제 더 도전적인 시나리오를 탐구해 보겠습니다. 학교 컬렉션을 가정해 보겠습니다. 각 학교는 여러 반을 가지고 있으며, 각 반은 여러 학생들을 가지고 있습니다:

db.schools.insertOne({
name: "Sunshine Elementary",
classes: [
{
name: "Class 1A",
students: [
{ name: "Alice", grade: "A" },
{ name: "Bob", grade: "B" }
]
},
{
name: "Class 1B",
students: [
{ name: "Charlie", grade: "A" },
{ name: "David", grade: "C" }
]
}
]
})

모든 반의 학생들의 성적을 인덱싱하려면 다음과 같이 합니다:

db.schools.createIndex({ "classes.students.grade": 1 })

이제 "A" 등급을 가진 학생들이 있는 모든 학교를 효율적으로 찾을 수 있습니다:

db.schools.find({ "classes.students.grade": "A" })

고급 인덱싱 기술

이제 우리가 다루었던 몇 가지 고급 인덱싱 기술을 요약하는 표를 보여드리겠습니다:

기술 설명 예제
다중 키 인덱스 배열 필드에 자동으로 생성되는 인덱스 db.books.createIndex({ authors: 1 })
복합 인덱스 여러 필드에 대한 인덱스 db.students.createIndex({ "address.city": 1, "address.zipcode": 1 })
텍스트 인덱스 텍스트 검색 쿼리를 가능하게 함 db.articles.createIndex({ content: "text" })
해시 인덱스 필드 값의 해시를 인덱싱 db.users.createIndex({ username: "hashed" })
와일드카드 인덱스 지정된 패턴에 매칭되는 필드를 동적으로 인덱싱 db.products.createIndex({ "details.$**": 1 })

사랑하는 학생들이여, 인덱싱은 강력한 도구이지만, 비용이 따릅니다. 각 인덱스는 공간을 차지하며 쓰기 연산을 늦추게 됩니다. 도서관에 더 많은 목록을 추가하는 것처럼, 인덱스는 책을 찾는 데 도움이 되지만, 새로운 책이 도착할 때 갱신하는 데 시간이 걸립니다.

이 수업을 마치면서, 한 학생이 물었던 질문이 떠오릅니다. "교수님, 인덱싱은 시험에서 치트 시트를 만드는 것과 같나요?" 그리고 알고 보면, 그 비유는 꽤 적절합니다! 인덱스는 데이터베이스의 치트 시트와 같아서, 필요한 정보를 빠르게 찾아주는 역할을 합니다.

계속 연습하고, 호기심을 유지하며, 행복하게 인덱싱하시길 바랍니다!

Credits: Image by storyset