500. 역색인 (Inverted Index)과 전문 검색 엔진
⚠️ 이 문서는 구글이나 네이버 검색창에 "가을 코트"라고 쳤을 때 1억 개의 웹페이지 중에서 0.1초 만에 결과를 뽑아오기 위해, **'책 번호'로 '글자'를 찾는 일반 DB의 방식을 완전히 뒤집어서, '글자'를 기준으로 '책 번호'를 묶어버리는 검색 엔진의 심장인 '역색인'**을 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 전통적인 B-Tree 인덱스가
ID -> 본문을 가리킨다면, 역색인(Inverted Index)은 문장을 단어 단위로 다 쪼갠 뒤에단어 -> 본문 ID 리스트를 가리키게 만든 거꾸로 된 목차다.- 가치: MySQL에서
LIKE '%검색어%'를 쓰면 1억 줄을 무식하게 다 읽어야(Full Scan) 하지만, 역색인은 그 단어가 있는 방 번호를 이미 다 적어놨기 때문에 0.01초 만에 결과를 던져준다.- 기술 체계: **ElasticSearch(엘라스틱서치)**의 핵심 작동 원리이며, 형태소 분석기(Tokenizer)를 통해 문장에서 불필요한 조사('은/는/이/가')를 버리고 의미 있는 명사만 뽑아내어 역색인을 구성한다.
Ⅰ. 개요: 1억 개의 자기소개서 뒤지기 (Context & Necessity)
"자기소개서에 '열정'이라는 단어가 들어간 지원자를 모두 찾아줘!"
- RDBMS (MySQL):
SELECT * FROM 지원서 WHERE 내용 LIKE '%열정%';- 결과: 인덱스를 탈 수 없다(
LIKE조건에 앞쪽 와일드카드%가 붙었기 때문 - 429번 문서). 1억 개의 자기소개서를 처음부터 끝까지 다 읽어보느라 서버가 죽는다.
- 결과: 인덱스를 탈 수 없다(
이 끔찍한 속도를 극복하기 위해 **역색인(Inverted Index)**이 등장했다. 지원서를 DB에 저장하기 전에, 글자를 모조리 다 찢어발긴다.
- 지원서 1: "나는 열정이 넘친다" $\rightarrow$
나,열정,넘침 - 지원서 2: "열정 페이는 싫다" $\rightarrow$
열정,페이,싫음
그리고 단어를 기준으로 새로운 목차를 만든다.
열정$\rightarrow$ [지원서 1번, 지원서 2번]페이$\rightarrow$ [지원서 2번]
이제 "열정"을 검색하면, 1억 개를 뒤질 필요 없이 목차에서 '열정'만 찾으면 바로 [1번, 2번]이라는 결과가 튀어나온다!
📢 섹션 요약 비유: 일반 DB가 **'책등(ID)'**을 보고 책을 꺼내서 한 장씩 넘겨가며 단어를 찾는 것이라면, 역색인은 책 맨 뒤에 있는 '찾아보기(색인)' 페이지입니다. '열정'이라는 단어를 찾으면 그 옆에 '15p, 30p, 102p'라고 적혀있어서 책 전체를 읽을 필요가 전혀 없죠.
Ⅱ. 역색인의 3단계 구축 과정 (Text Analysis) ★
글을 냅다 저장한다고 역색인이 만들어지지 않는다. 중간에 빡센 정제 과정이 필요하다.
1. Tokenizer (토크나이저 - 쪼개기)
- 문장을 의미 있는 최소 단위의 단어(Token)로 쪼갠다.
- "데이터베이스가 참 재밌다" $\rightarrow$
[데이터베이스가, 참, 재밌다]
2. Filter (필터 - 걸러내기 및 다듬기)
- Stop Word (불용어) 제거: '은, 는, 이, 가, 참, 매우' 같이 검색에 아무 쓸모없는 글자들을 휴지통에 버린다.
- Stemming (어근 추출): '재밌다', '재밌네', '재밌어'를 모두
재미라는 기본형 텍스트로 통일시킨다. (검색어와 잘 매칭되도록) - 소문자 변환:
DataBase$\rightarrow$database
3. Inverted Index 생성 (묶기)
- 정제가 끝난 토큰들을 오름차순(가나다순)으로 정렬하고, 그 옆에 해당 단어가 등장했던 문서의 ID 리스트(Posting List)를 주렁주렁 매단다.
Ⅲ. 실무 활용: ElasticSearch와 RDBMS의 콤비 플레이
"그럼 역색인이 짱이니까 무조건 엘라스틱서치만 쓰면 되겠네요?" 절대 아니다. 역색인은 검색에는 신이지만, 트랜잭션(업데이트)에는 최악이다.
- 만약 지원자가 자기소개서를 수정(
UPDATE)했다면? - MySQL은 자기소개서 내용 1줄만 덮어쓰면 끝이다.
- 엘라스틱서치는 수정한 글자를 다시 다 쪼개고(Tokenizer), 역색인 목차 수천 개를 다 열어서 문서 ID를 넣었다 뺐다 해야 한다. (CPU 비명)
그래서 실무에서는 철저하게 역할을 나눈다.
- 결제, 가입, 수정 (OLTP): 무조건 **RDBMS (MySQL)**가 뼈대를 잡는다.
- 검색창 (Search): MySQL에 데이터가 들어오면 CDC(490번 문서)나 Kafka를 통해 ElasticSearch로 데이터를 실시간 복사한다. 유저가 검색창에 글자를 치면 무조건 엘라스틱서치만 찔러서 역색인의 무지막지한 검색 속도를 100% 누린다.
┌──────────────────────────────────────────────────────────────┐
│ RDBMS의 B-Tree vs ElasticSearch의 역색인 비교 시각화 │
├──────────────────────────────────────────────────────────────┤
│ │
│ [ 🌲 RDBMS (B-Tree Index) ] │
│ ID(PK) ──▶ 데이터 본문 │
│ 1번 문서 ──▶ "안녕하세요 저는 백엔드 개발자입니다." │
│ 2번 문서 ──▶ "훌륭한 개발자는 치킨을 좋아합니다." │
│ ★ 특징: "치킨"을 검색하려면 1번, 2번 문서를 다 열어서 글자를 읽어봐야 함. │
│ │
│ [ 📖 ElasticSearch (Inverted Index) ] │
│ 단어(Token) ──▶ 포함된 문서 ID 리스트 (Posting List) │
│ "개발자" ──▶ [ 1번, 2번 ] │
│ "백엔드" ──▶ [ 1번 ] │
│ "치킨" ──▶ [ 2번 ] │
│ ★ 특징: "치킨"을 검색하면 목차에서 "치킨"만 딱 찾고 끝! 바로 [2번] 리턴. │
└──────────────────────────────────────────────────────────────┘
Ⅳ. 결론
"검색의 속도를 위해 삽입의 고통을 기꺼이 감수하다."
역색인은 빅데이터 시대에 정보 검색(Information Retrieval)의 패러다임을 바꾼 위대한 발명품이다. 우리가 쿠팡이나 배달의민족 검색창에 띄어쓰기를 틀리거나 오타를 내도('나이키' $\rightarrow$ '나이기') 찰떡같이 원하는 상품을 찾아주는 것은, 이 역색인과 형태소 분석기가 보이지 않는 곳에서 미친 듯이 일하고 있기 때문이다. 백엔드 엔지니어는 자신이 다루는 데이터가 '정확한 일치(=)'가 필요한지, 아니면 '문맥과 키워드 검색(LIKE)'이 필요한지를 구분하여 RDBMS와 검색 엔진(역색인)을 하이브리드로 엮어내는 아키텍처 설계 능력을 반드시 갖추어야 한다.
📌 관련 개념 맵
- 관련 데이터베이스: ElasticSearch, Solr, Lucene
- 대척점 아키텍처: B+Tree Index (422번 문서 - PK나 숫자 범위 검색에 유리)
- 보완 아키텍처: Vector DB (485번 문서 - 단어의 빈도가 아니라 '의미/문맥'을 유사도 랭킹으로 찾을 때 사용)
- 데이터 동기화 기술: CDC (Change Data Capture - 490번 문서)
👶 어린이를 위한 3줄 비유 설명
- B-Tree는 책의 목차예요. "3단원은 50페이지에 있어!"라고 알려주죠.
- 하지만 "이 책에서 '사과'라는 단어가 어딨지?" 찾으려면 1페이지부터 다 읽어야 하잖아요?
- 역색인은 책 맨 뒤에 있는 찾아보기(색인) 페이지예요! '사과'를 찾으면 옆에 "12p, 45p, 80p"라고 적혀있어서 1초 만에 책의 구석구석을 다 찾아볼 수 있답니다!