VectorDB
1. 소개
데이터베이스(DB)는 본질적으로 정보를 체계적으로 저장하고, 필요할 때 원하는 데이터를 빠르게 추출하기 위해 정리된 창고와 같다. IT 기술이 발전함에 따라 데이터의 형태가 단순한 텍스트와 숫자에서 복잡한 비정형 데이터로 확장되었고, 이에 맞춰 DB의 패러다임도 관계형 데이터베이스(RDB)에서 도큐먼트 DB(Document DB), 그리고 최근의 벡터 DB(Vector DB)로 진화해 왔다.
| 구분 | Relatioinal DB | Document DB |
|---|---|---|
| 등장 배경 | 정형 데이터, 트랜잭션 중심 업무 | 비정형/반정형 데이터 증가 |
| 데이터 관리 | 정규화로 중복 최소화 | 중복 허용 (읽기 성능 우선) |
| 처리 가능한 질문 | 값의 존재와 value | 값의 존재 |
| 검색 기준 | 정확히 값은 값 (컬럼 값 비교) | 정확히 같은 값 (필드 값 비교) |
| 스키마 | 정해진 구조 | 유연한 구조 |
| 데이터 형태 | 테이블 | 문서 |
2. DB의 진화
2-1. 기존 DB vs VectorDB
기존 DB 설계가 잘못되었다라는 것이 아니라, LLM의 등장으로 데이터 비교 기준의 변화가 일어났다. 즉, 단순히 특정 값의 존재와 value에서 뛰어났던 SQL/NoSQL에서 앞선 대화에서 그 값의 의미는 무엇인가? 등의 사용자 쿼리로 변화가 일어난 것이다.
| 구분 | 기존 DB | Vector DB |
|---|---|---|
| 목적 | 값을 저장하고 비교하는 시스템 | 의미를 숫자로 저장하고 비교하는 시스템 |
| 데이터 관리 | 값 (숫자, 문자열) | 벡터 (숫자 배열) |
| 처리 가능한 질문 | 값이 있는가? 값이 같은가? | 얼마나 비슷한가? |
| 검색 기준 | 정확히 같은 값 | 의미적으로 유사한 데이터 (거리 계산) |
2-2. 머신과 텍스트
예금 계좌,저축 계좌,Deposit Account
일반적으로 머신은 텍스트를 이해할 수 없다. 사람은 위 3개의 단어를 거의 같은 의미로 이해하지만, 머신은 서로 다른 문자열로 인식할 수도 있다. 다만 문자열이 달라도 의미가 비슷하면 벡터값도 비슷한 점을 이용해서, 이 벡터들과 얼마나 가까운가를 판별해 작동하는 것이다. 결국 우리는 텍스트를 머신이 인식할 수 있도록 바꾸어야만 한다. 그 관점에서 아래 개념에 대한 이해가 필요하다.
2-3. 머신에게 텍스트 이해시키기
텍스트를 머신이 인식할 수 있는 수치 데이터로 변환하는 과정에서 핵심이 되는 개념이 토큰, 임베딩, 그리고 인코딩이다.
Token
- 텍스트를 처리 가능한 최소 단위로 분할한 조각을 의미한다.
- 문장을 단어 또는 서브워드(Sub-word) 단위로 쪼개어 나눈 결과물이다. 예를 들어 "I love orange"라는 문장은 'I', 'love', 'orange'라는 세 개의 토큰으로 분리된다.
Embedding
- 각 토큰을 고정된 벡터 공간의 수치로 변환한 표현 방식이다.
- 이를 단어별 의미 점수표 라고도 부르며, 정적인 의미 공간 내 에서 단어에 의미를 부여한 숫자 ID 카드와 같다.
- 예를 들어 'love'라는 단어는
[0.12, -0.87, 0.55, ..., 0.03]과 같은 특정 벡터값으로 치환되어 신경망 학습에 활용된다.
Encoding
- 토큰의 위치나 문맥적 정보까지 반영한 고차원 표현 방식이다.
- 임베딩이 정적인 점수표라면, 인코딩은 문장 속에서 달라지는 동적인 문맥적 의미 를 담는다.
- 동일한 단어라도 문장 내 위치와 주변 단어에 따라 인코딩된 결과값은 달라질 수 있다.
Dimension
- 벡터 공간의 축, 즉 차원을 디멘션이라고 한다.
- 벡터 DB 설계 시 이 디멘션을 어떻게 설정하느냐가 성능의 핵심 지표가 된다.
- 최근에는 서비스의 특성과 데이터의 성격에 따라 최적의 차원 수가 어느 정도 정형화되는 추세이다.
- 저차원 (Low Dimension)
- 간단한 패턴을 표현하기에 적합.
- 거리 기반으로 유사도를 명확히 판단.
- 하지만 정보 손실이 발생 가능.
- 고차원 (High Dimension)
- 복잡하고 추상적인 개념을 세밀하게 표현.
- 그러나 차원이 너무 높아지면 ... 모든 벡터 간의 거리가 멀어져 유사도 판단이 어려워지는 차원의 저주 현상이 발생 가능
3. Vector DB
3-1. Vector DB의 정체
RDB가 Row와 Column을 기준으로 삼고, NoSQL이 Key와 Field를 기준으로 한다면, 벡터 DB는 벡터(Vector)와 메타데이터(Metadata) 를 저장 단위로 삼는다.
기존 RDB가 다음과 같았다면...
COLUMNS (열 방향) -------------------------->
+-----------+------------+------------+------------+
| ID | COL 1 | COL 2 | COL 3 | <-- Primary Key (ID)
+-----------+------------+------------+------------+
R | ID | Field Data | Field Data | Field Data |
O +-----------+------------+------------+------------+
W | ID | Field Data | Field Data | Field Data |
S +-----------+------------+------------+------------+
| ID | Field Data | Field Data | Field Data |
| +-----------+------------+------------+------------+
|
v (행 방향)
VectorDB는 아래와 같다!
DIMENSIONS (벡터 차원) ---------------------->
+-------+ +---------------------------+ +-----------+
| id |---| vector |---| meta data |
+-------+ +---------------------------+ +-----------+
P +-------+ +---------------------------+ +-----------+
O | id |---| vector |---| meta data |
I +-------+ +---------------------------+ +-----------+
N +-------+ +---------------------------+ +-----------+
T | id |---| vector |---| meta data |
S +-------+ +---------------------------+ +-----------+
+-------+ +---------------------------+ +-----------+
| | id |---| vector |---| meta data |
| +-------+ +---------------------------+ +-----------+
v
(포인트 방향)
이렇게 벡터 DB는 단순한 수치 저장소가 아니라, 의미 기반 유사도 검색을 위해 설계된 특화 구조를 가진다.
| 구성 요소 | 상세 내용 | RDB 대응 개념 |
|---|---|---|
| Collection | 벡터들을 그룹화한 저장 단위 | Table |
| Point | 벡터 하나의 데이터 단위 (ID, Vector, Payload로 구성) | Row |
| ID | 각 Point를 식별하는 고유값 (주로 UUID) | Primary Key |
| Vector | 다차원 수치 임베딩 데이터 | Field Data |
| Metadata | 벡터에 부가된 설명 정보 (필터링용) | Column |
3-4. 벡터 검색과 코사인 유사도
벡터 DB는 정확한 키워드 매칭이 아니라, 벡터 간의 거리를 계산하여 유사한 의미 를 찾는다. 이때 주로 활용되는 것이 코사인 유사도 이다.
학창시절 기하와 벡터에서 배우는 기본적인 내적 개념과 동일하다. 코사인 유사도는 두 벡터 간의 각도를 계산하여 유사성을 평가하는 기법이다. 여기서 중요한 점은 벡터의 크기가 아니라 방향 에 초점을 맞춘다는 것이다. 수식적으로는 분자에 두 벡터의 내적을, 분모에 각 벡터의 노름 곱을 배치하여 계산한다.
검색 시에는 거리 기반으로 가장 유사한 개의 결과를 반환하는 Top-k 방식을 사용한다. 실무에서는 보통 값을 3 또는 5로 설정한다. 이때 3순위 이후의 결과가 유효하지 않다고 해서 이를 억지로 거르기 위해 과도한 로직을 짜는 것보다, 적절한 임계치를 설정하는 것이 효율적이다.
4. Vector & Embedding
4-1. Embedding 모델
Embedding 모델은 사람이 쓰는 언어를 기계가 처리 가능한 형태로 변환한다. Embedding을 사람이 직접 관찰하고 그 의미를 파악하기는 어려우나, 서로 다른 단어 또는 문서로부터 추출된 Embedding vector 간의 거리를 계산하면 이들 간의 의미적 관계를 파악할 수 있다.
도메인 특성(의료, 법률, 반도체 등)이 강할 경우 Embedding 전용 모델을 재학습해야 할 수도 있지만, 일반적인 경우에는 공개된 사전 학습 모델을 사용해도 무방하다. 현업에서는 상용 모델을 사용하는 경우도 있고, 오픈소스 모델을 로컬로 내려서 사용하는 경우도 있다. 아래 표는 다양한 Embedding 모델의 특징을 정리한 것이다.
| 구분 | OpenAI Embedding | Cohere Embedding | Upstage Embedding | SBERT / E5 계열 |
|---|---|---|---|---|
| 특징 | 글로벌 범용, 기준이 되는 임베딩 | 검색 특화 | 한국어 특화 | 오픈소스, 목적이 드러나는 임베딩 |
| 학습 데이터 | WEB, Q&A, 기술문서, 대화체 혼합 | 검색 쿼리 – 문서 페어 | 뉴스, 리포트, 업무 문서 | QA, retrieval, paraphrase |
| 임베딩 성향 | 고차원 | 중간 수준 | 비교적 적은 수준 | 중간 수준 |
| 검색 특징 | 개념 중심 설명 문서가 상위에 노출되는 경향 | 질문 의도에 맞는 결과, 질문-답변 관계가 명확하지 않은 문서에는 불리 | 실제 문서/사례 중심, 범용 질문에서 과도한 제한 (문서 문맥 우선) | 목적에 맞는 정밀 검색 가능, 학습 목적과 다른 질의 대응 어려움 |
| 대표 모델 | text-embedding-3-large, text-embedding-3-small | Embed-multilingual-v3.0 | solar-embedding-1-large, solar-embedding-1-small | e5-large, e5-small, mpnet |
4-2. Embedding의 단위
임베딩 시 문서를 어떤 단위로 자를 것인가가 중요하다. 절대적인 기준은 없으나, 실무에서는 관리 편의를 위해 일정한 글자 수로 자르는 방식도 흔히 사용된다.
- 문장 단위: FAQ나 짧은 질의응답에 적합하다.
- 문단 단위: 매뉴얼이나 기술 문서에 유리하다.
- 문서 단위: 논문이나 리포트 분석에 쓰인다.
4-3. 메타데이터의 활용
검색 품질을 높이기 위해 벡터와 함께 저장하는 메타데이터 정보이다. 문서를 관리할 때는 PDF 형식을 권장한다. 텍스트 추출 과정에서 메타데이터 정리가 용이하고 인코딩 깨짐 현상을 방지할 수 있기 때문이다. 또한 균일한 형식의 파싱 라이브러리도 다양하게 존재한다.
- 문서 자체에 이미 포한된 구조적 정보
- 제목, 문서 ID, 작성일, 언어 등
- 문서와 함께 시스템이 알고있는 정보
- 저장 위치, 접근 권한, 우선순위 등
- 문서 본문에는 없지만, 검색 설계 상 이미 확보 가능한 정보
- LLM 생성 정보
- 검색 성능/품질 확보를 위해 LLM을 통해 보조 정보를 추가할 수 있음
- 요약본 등 검색 성능 확보를 위한 추가 텍스트
- 사람이 직접 입력
- 검색 효율을 위해 사람이 직접 정보 추가
- 작성년월 등 (문서에 작성일 정보가 없는 경우)
4-4. 검색
검색 시 사용자의 쿼리 부터 최종 검색 결과 반환 까지의 과정을 압축하면 다음과 같다.
- 유저가 쿼리를 날리면 쿼리 임베딩
- Vector Similarity Search (Top-k)
- metadata 필터 또는 그냥 개발자가 개입해서 소팅을 하는 경우도 존재한다.
- 최종 검색 결과 반환
5. Index 구조
벡터 검색은 차원이 높아질수록 연산 비용이 급증한다. 따라서 모든 데이터를 전수 조사하는 정확 검색(Flat)보다는 근사 검색(ANN: Approximate Nearest Neighbor) 방식을 주로 택한다. 이는 정답을 100% 보장하기보다, 정답일 확률이 높은 후보를 빠르게 찾아내는 장치이다.
5-1. Vector Index 설계방향
- 정확성보다 속도!
- Index 의 역할 재정의
- 정답을 찾는 장치가 아님
- 정답일 확률이 높은 후보를 빠르게 모으는 장치
- Retrieval(2단계 검색)
- 1단계 검색: Index 단계로, 전체 중 일부 후보 선택
- 2단계 검색: 후보 대상으로만 정확한 계산 후 Top-k 확정
5-2. Vector Index 종류
Flat
모든 후보를 그대로 두는 유일한 방식이다. Index 없이 전수 비교를 통해 정확도 100%를 달성하는 것이 목표! 물론 정답을 보장하지만, DB 규모가 커질수록 매우 비효율적이다.
- 활용 포인트
- 데이터가 작을 때
- Index 품질 검증 밑 기준 성능 측정용
IVF Index
Inverted File Index 로, 정답 후보를 묶음 단위로 줄이는 전략이다.
우선 전체 벡터를 여러 개의 군집으로 사전에 분할한다.
이후 검색 단계에서 사용자 쿼리와 가까운 군집을 선택하며, 해당 군집 내에서만 정밀하게 거리 계산을 수행한다.
- Index 관리
- 전체 벡터 공간을 대표 벡터(Centroid) 기준으로 분할
- 각 벡터는 가장 가까운 Centroid에 할당
- Index는 Centroid → Inverted List(소속 벡터 목록) 구조로 관리
- 장단점
- 비교 대상 수를 대폭 감소 → 속도 개선
- 대규모 데이터에서도 현실적인 검색 가능
- 군집을 적게 보면 : 속도 ↑, Recall ↓ (Trade-off)
- 군집을 많이 보면 : 속도 ↓, Recall ↑ (Trade-off)
- 활용 포인트
- 데이터 규모가 크고 분포가 비교적 안정적일 때
- 전체 검색 보다는 빠른 응답이 중요한 서비스
HNSW Index
Hierarchical Navigable Small World Index 으로, 이웃을 따라 이동하며 후보를 줄이는 전략이다.
Graph 구조로 벡터가 가까운 이웃 벡터들과 연결되도록 구성한다.
검색 시 가까운 이웃을 따라 점진적으로 이동하며 후보 탐색하며, 전체를 나누지 않고 가까운 것부터 타고 들어가는 방식이다.
즉, 후보를 공간이 아닌, 관계(이웃)로 줄이는 전략이다.
- Index 관리
- 자신과 가까운 벡터들과 Edge로 연결
- 그래프는 여러 층으로 구성 (상위는 빠르게, 하위 레벨로 정밀하게 탐색)
- 장단점
- 데이터 분포 변화에 강건
- Index 구축 비용 큼 (메모리 사용량 ↑)
- 구조가 복잡하여 개념 이해 난이도 있음
- 연결을 많이 할수록 : 속도 ↓, Recall ↑
- 탐색 범위를 줄이면 : 속도 ↑, Recall ↓
- 활용 포인트
- 데이터 분포가 자주 변하거나 동적인 환경
- 메모리 비용을 감수하더라도 안정적인 검색 품질이 요구되는 경우
PQ Index
Product Quantization Index 로, 벡터를 압축해 비교 비용을 줄이는 전략이다.
고차원 벡터를 여러 개의 부분(sub-vector, segment)로 분할하고, 각 부분을 대표 코드(centroid, codeword)로 근사 표현한다.
즉, 실제 벡터 대신 압축된 코드로 거리 계산을 수행하며, Recall(정확도)을 희생하고 비용을 극단적으로 줄이는 전략이다.
Recall은 진짜 정답이 후보군 안에 포함될 확률을 뜻하며, 현업에서는 리콜 값이 0.4 정도만 나와도 준수한 성능으로 간주하기도 한다.
- Index 관리
- 하나의 벡터를 여러 조건으로 분해 (e.g. 256D → 8개 sub-vector)
- 각 벡터를 가장 가까운 대표 코드로 치환
- 실제 값이 아닌 code index 조합으로 저장
- 장단점
- 메모리 사용량 대폭 감소, 거리 계산 비용 현저히 감소
- 원본 벡터를 그대로 보지 않아 근사 오차 발생 → Recall 저하 가능성
- 압축 정도가 커질수록 : 속도 ↑, 메모리 ↓, Recall ↓
- 압축을 완화할수록 : 속도 ↓, 메모리 ↑, Recall ↑
- 활용 포인트
- 벡터 수가 수천만~수억 단위로 매우 큰 경우
- 약간의 정확도 손실을 감수하고 대규모 검색이 요구될 경우
표로 정리해보자면
| 구분 | Flat | IVF | HNSW | PQ |
|---|---|---|---|---|
| 특징 | 모든 벡터와 직접 거리 계산 (Exhaustive Search) | 벡터를 클러스터링 한 후에 해당 클러스터 내에서만 탐색 | 그래프 기반 탐색, 다단계 계층적 그래프 구조 | 벡터를 압축하여 저장, 거리 계산은 근사값 |
| 계산 | Nearest Neighbor | ANN | ANN | ANN |
| 적합한 경우 | 소형 테스트 시 유용 | 중~대규모 데이터셋 | 실시간 검색, 정밀도-속도 균형 고려 | 모바일, 임베디드 환경 |
| 장점 | 정확도 100%, 정확한 최근접 이웃 | 속도 빠름, 검색 공간 축소 | 빠른 검색, 정밀도 높음 | 빠른 근사 검색, 저장공간 절감 |
| 단점 | 속도 느림, 대규모 처리 비효율 | 정밀도 저하, nprobe 조절하여 속도/정확도 균형 조정 가능 | 인덱스 구축에 메모리 소모, 벡터 삽입 느림 | 정확도 저하, 압축 따른 정보 손실 |
| 예시 | FAISS (feat. Scikit-learn) | Pinecone, FAISS, Milvus | Qdrant, Weaviate, Vespa.ai | FAISS, Annoy (Spotify) |
6. VectorDB 종류
AI 서비스 개발 중 마주칠 수 있는 VectorDB에 대해서 정리해보자.
FAISS
- 주요 기능
- DB가 아닌 벡터 유사도 검색을 위한 고성능 라이브러리
- 다양한 Index 알고리즘을 제공하며 CPU와 GPU 환경을 모두 지원
- 장단점
- 매우 빠른 검색 성능을 자랑하며, 알고리즘 수준에서의 자유도가 높음
- DB로서의 기능이 부재하며 직접 운영/관리해야 할 요소가 많음
- 데이터 저장 기능, 메타데이터 관리, 권한/보안, 운영 기능(백업, 모니터링 등)은 제공 ❌
Milvus
- 주요 기능
- 벡터 검색 엔진 위에 저장, API, 운영 기능을 결합한 서버형 Vector DB
- 메타데이터 기반 검색이 동시에필요하거나 확장성과 안정성이 중요한 대형 서비스에 사용
- 장단점
- 대규모 데이터 처리에 적합하며, 검색과 필터링을 함께 지원
- 서버 및 클러스터 구성이 필요하여 인프라 관리 부담이 있고, 초기 설정이 복잡
Qdrant
- 주요 기능
- 벡터 검색을 중심으로 개발 친화성과 단순 운영을 강조한 서버형 Vector DB
- 메타데이터 기반 검색이 중요한 비중을 차지하거나 인프라 복잡도를 피하고 싶은 경우 사용
- Rust 기반 구현으로 안정성과 성능을 확보
- REST API 중심의 직관적인 인터페이스를 제공
- 장단점
- API 설계가 직관적이며 메타데이터 필터링 능력이 우수
- 대규모 환경에서는 한계가 있을 수 있음 (Milvus 대비 대규모 분산 처리에는 제약이 존재)
Chroma
- 주요 기능
- 운영과 인프라를 최소화하고, 개발과 실험에 집중할 수 있도록 설계된 Vector DB
- 서버 운영 기능, 분산 아키텍처, 대규모 확장 기능은 의도적으로 포함하지 않음
- 개발, 연구, 프로토타입 단계인 경우 RAG 설계 단계인 경우 사용
- 별도 서버 없이 로컬 환경에서 바로 사용이 가능
- 장단점
- 설치 및 사용이 매우 간단하여 개발 초기 학습 비용을 최소화
- 대규모 서비스 운영에는 부적합하며 확장성과 안정성에 제한
Pinecone
- 주요 기능
- 벡터 검색과 운영을 클라우드 서비스 형태로 제공하
- 서버 및 클러스터 구성, 인덱스 운영, 인프라 관리 등을 모두 담당해줌
- 장단점
- 운영 부담이 최소화
- 비용과 통제력 측면의 고려가 필요