Elasticsearch vs RDB

Elasticsearch란? RDB와 비교를 곁들인

Posted by Yan on April 13, 2025

Elasticsearch

  • Java 오픈소스 분산 검색 엔진
  • 방대한 양의 데이터를 신속하게, 거의 실시간( NRT, Near Real Time )으로 저장, 검색, 분석할 수 있다.
  • ES는 역색인을 지원하기에 기존 RDB가 지원하지 않는 비정형 데이터를 인덱싱 + 검색하는 것에 특화되어있다.
    • 비정형 데이터: 규칙이 없는 데이터. ex) 음성, 텍스트, 영상
    • 역색인 : 키워드를 통해 데이터를 찾는 방식
  • 검색을 위해 단독으로 사용되기도 하며, ELK( Elasticsearch / Logstatsh / Kibana )스택으로 사용되기도 한다.

ELK

  • Logstash : 다양한 소스( DB, csv파일 등 )의 로그 또는 트랜잭션 데이터를 수집, 집계, 파싱하여 Elasticsearch로 전달
  • Elasticsearch: Logstash로부터 받은 데이터를 검색 및 집계를 하여 필요한 관심 있는 정보를 획득
  • Kibana : Elasticsearch의 빠른 검색을 통해 데이터를 시각화 및 모니터링

RDB와 비교

  • RDB의 경우 모든 row를 읽어서 스페이스를 딜리미터로 파싱한 뒤, 홍길동 포함여부를 조사해야한다. 따라서 모든 row를 읽어야만 하기에 상당한 검색시간이 소요된다.
  • 반면 ES는 저장할 때부터 토큰화하여 역색인 인덱스에 (id, 단어, doc_id) 형태로 저장한다. 따라서 특정 row만 읽고 검색이 가능하다. 단어를 포함하는 doc_id 를 쉽게 알 수 있으며 빠른 검색이 가능하다.

Elasticsearch 사용 방식

데이터 넣기 (Indexing)

  • ES에서 데이터를 저장하는 단위를 “문서(Document)”라고 부르고, 이 문서는 JSON 형식으로 저장
  • 내부적으로 역색인(inverted index) 구조를 사용해 텍스트 기반 검색을 최적화된 방식으로 저장
1
2
3
4
5
6
7
POST /products/_doc/1
{
  "name": "MacBook Pro",
  "price": 2999,
  "category": "laptop",
  "description": "Apple laptop with M2 chip"
}
  • products: 인덱스 이름 (RDB의 테이블 역할)
  • _doc: 타입 (ES 7.x 이후 거의 고정됨)
  • 1: 문서 ID (없으면 ES가 자동 생성)
  • 본문: JSON 데이터

검색하기 (Querying)

검색 시에는 SQL이 아닌 ES DSL(Domain Specific Language)이라는 JSON 기반 쿼리를 사용

전체 텍스트 검색 (Full-text Search) 예:

1
2
3
4
5
6
7
8
GET /products/_search
{
  "query": {
    "match": {
      "description": "apple laptop"
    }
  }
}

조건 검색 (Filtering) 예:

1
2
3
4
5
6
7
8
9
10
11
12
13
GET /products/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "category": "laptop" } }
      ],
      "filter": [
        { "range": { "price": { "lt": 3000 } } }
      ]
    }
  }
}
  • match는 분석기(analyzer)를 거쳐 자연어 처리 기반 검색을 수행합니다.
  • filter는 분석 없이 조건 매칭만 수행하므로 캐싱이 가능하고 빠르다.
    • Analyzer: 문장을 쪼개고(lowercase, stemming 등) 인덱싱할 때 쓰는 도구

RDB와 비교

✅ ES vs RDB 비교

구분 RDB (예: MySQL, Oracle) ElasticSearch
목적 데이터의 정합성 & 트랜잭션 중심 저장 빠르고 유연한 검색과 집계
데이터 구조 테이블 - 행(row), 열(column) 기반 인덱스 - 문서(document, JSON 기반)
스키마 엄격한 스키마 기반 (DDL) 스키마리스, 유연한 매핑 (자동 추론 가능)
질의 언어 SQL DSL (JSON 기반 도메인 쿼리)
검색 기능 정확한 값 비교 중심 (LIKE 포함) 자연어 기반 Full-Text Search, 정규화된 색인 기반
인덱싱 구조 B-Tree 기반 (주로 PK, FK 인덱스) Inverted Index (역색인, 텍스트 검색 최적화)
성능 수직적 확장 (Scale-up 위주) 수평적 확장 (Scale-out, 샤딩/레플리카)
정합성 ACID 지원 (트랜잭션 강함) 기본은 Eventually Consistent (최종 일관성)
사용 예 금융 트랜잭션, ERP, OLTP 검색엔진, 로그 분석, 대시보드, 추천

✅ 주요 차이점

1. 🔍 검색 방식

  • RDB는 LIKE, =, IN, BETWEEN 같은 정확한 조건 검색 위주
    • 예: WHERE title LIKE '%laptop%'
  • ES는 match, full-text search, fuzzy, n-gram, autocomplete 등 다양한 검색이 자연어 기반으로 지원됩니다.
    • 예: “애플 랩탑” → “apple laptop”을 자동 매칭

2. ⚙️ 인덱싱 구조

  • RDB: B-Tree 인덱스는 “정렬/범위 기반 탐색”에 특화됨
  • ES: Inverted Index는 “단어 → 문서 ID 리스트”를 미리 저장해놓고 검색 최적화에 탁월

3. 💾 데이터 저장과 정합성

  • RDB는 BEGIN, COMMIT, ROLLBACK트랜잭션 처리로 정합성 보장
  • ES는 기본적으로 트랜잭션이 없으며, 분산 구조에서 일관성은 eventual consistency

4. 🧠 모델링 철학

  • RDB는 정규화 중심 (관계로 데이터 분리, Join으로 결합)
  • ES는 비정규화 중심 (Join이 없거나 제한적 → 필요한 모든 필드를 한 문서에 넣는 방식)

✅ RDB의 Join과 비교해보면

ElasticSearch는 전통적인 RDB의 Join 기능이 매우 제한적이라서, 보통은 다른 방식으로 우회하거나 데이터 모델링 자체를 바꾸는 경우가 많다고 한다.

구분 RDB ElasticSearch
Join 방식 INNER, LEFT, RIGHT, OUTER 등 자유로운 조인 Join 자체가 없음 (제한된 nested, parent-child만 지원)
관계 설정 외래키 기반 다대일, 일대다, 다대다 관계 명확 대부분 비정규화하거나, nested/parent-child 구조로 우회
성능 영향 Join 많아지면 느려질 수 있음 Join 자체가 없으므로 검색에 최적화됨

✅ ES에서 Join을 대체하는 3가지 방법

1. 데이터 비정규화 (Denormalization) ✅ 가장 일반적

예시 상황:
  • user 테이블 (id, name)
  • order 테이블 (id, user_id, amount)

→ ES에서는 order 문서에 user 정보까지 통째로 포함하는 방식으로 해결

1
2
3
4
5
6
{
  "order_id": 123,
  "user_id": 1,
  "user_name": "헤밍웨이",
  "amount": 10000
}

📌 장점: 검색 속도 매우 빠름
📌 단점: user name이 바뀌면 관련된 모든 order 문서를 갱신해야 함 (중복 데이터 관리 필요)


2. Nested 타입 (JSON 배열 내부에 문서 형태로 저장)

예시 상황:
  • 상품(product)에 리뷰가 여러 개 붙는 구조 (1:N)
1
2
3
4
5
6
7
{
  "product_name": "노트북",
  "reviews": [
    { "author": "개츠비", "score": 5 },
    { "author": "골드문트", "score": 4 }
  ]
}

📌 특징:

  • nested 타입으로 선언해야 함
  • nested query를 사용해 내부 필드 조건으로 검색 가능

쿼리 예시:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
  "query": {
    "nested": {
      "path": "reviews",
      "query": {
        "bool": {
          "must": [
            { "match": { "reviews.author": "개츠비" } },
            { "match": { "reviews.score": 5 } }
          ]
        }
      }
    }
  }
}

📌 일반 query로 하면 "개츠비""5"가 서로 다른 리뷰 객체에서 나와도 매칭될 수 있어서 nested가 필요함

Refernce

[Elasticsearch] 기본 개념잡기