seungjun.dev

벡터 데이터베이스

벡터 데이터베이스에 대해

제 블로그의 데이터베이스 시리즈에서 이 글에 있는 지식들이 대부분 있으니 참고하시면 좋겠습니다!

정의

수많은 벡터들을 어딘가에 저장하고, 필요할 때 빠르고 효율적으로 꺼내 쓰기 위한 DB

벡터 DB는 고차원의 벡터 데이터를 저장, 관리, 검색하는 데 특화된 DB다. 텍스트, 이미지, 오디오와 같은 비정형 데이터를 벡터 임베딩이라는 과정으로 숫자 배열 형태로 바꿔 저장한다. 벡터 임베딩 글 보러가기

기존의 관계형 DB(RDBMS)가 '나이가 30 이상인 서울 거주자'처럼 정해진 조건에 맞는 데이터를 찾는 데 최적화되어 있다면, 벡터 DB는 "이 문장과 가장 유사한 의미의 문서를 찾아줘" 와 같은 유사도 기반 검색에 특화되어 있다.

일반 DB에 벡터를 저장하지 않는 이유

일반 DB에 벡터(숫자 배열)를 저장할 수는 있다.

그러나 수백, 수천 차원이 넘는 벡터들 사이의 유사도를 계산해 가장 비슷한 것을 찾는 작업은 매우 비효율적이다.

그래서 벡터 DB를 쓴다. **ANN(Approximate Nearest Neighbor, 근사 최근접 이웃)**이라는 기술과 특별한 인덱싱 기법을 사용한다. 100% 정확한 값을 찾는 대신, 약간의 오차를 허용하면서도 '거의 정확한' 결괏값을 압도적으로 빠른 속도로 찾아낸다.

저장 방식

  • 특수 데이터 구조: 벡터는 부동 소수점 숫자 배열로, 데이터베이스 내에서 이를 효율적으로 처리하기 위한 전용 컬럼이나 필드에 저장된다.
  • 인덱싱 (Indexing): 방대한 양의 벡터 중에서 특정 벡터와 유사한 벡터들을 빠르게 찾기 위해 특별한 인덱스를 생성한다. 이 인덱스는 원본 데이터와는 별도로 저장되어 검색 성능을 최적화한다.

데이터베이스의 특성에 따라 벡터와 인덱스를 메모리에 저장해 빠른 접근을 우선시하거나(인메모리) 디스크에 저장해 영속성과 확장성을 확보하거나, 두 방식을 혼합할 수 있다.

검색 방식

다음과 같은 단계로 이루어진다.

  1. 벡터 임베딩: 검색하려는 대상 데이터를 임베딩 모델을 사용해 숫자 벡터로 변환한다.
  2. 유사도 측정 기준 정의: 벡터 간의 유사성을 측정할 수학적 방법을 정의한다. (코사인 유사도, 유클리드 거리 등)
  3. 쿼리 처리: 사용자가 입력한 검색어(쿼리) 역시 동일한 임베딩 모델을 통해 벡터로 변환된다.
  4. 유사도 계산 및 결과 순위화: 저장된 수많은 벡터들 중에서 쿼리 벡터와 가장 가까운(유사도가 높은) 벡터들을 찾아 순위를 매긴다.
  5. 근사 근접 이웃 탐색(ANN): 수백만, 수십억 개의 벡터 전체와 일일이 비교하는 것은 비효율적이다. 따라서 대부분의 벡터 DB는 ANN이라는 알고리즘을 사용한다.

유명 벡터 데이터베이스

데이터베이스특징저장/검색/인덱싱 방식
Pinecone완전 관리형 클라우드 서비스(SaaS), 사용하기 쉬운 API 제공, 개발자 친화적사용자가 내부 동작을 크게 신경 쓰지 않아도 되도록 추상화되어 있음. 다양한 ANN 인덱스 유형(Pod-based)을 제공하며, 메타데이터 필터링과 결합한 효율적인 검색 지원
Weaviate오픈소스, 벡터와 함께 원본 데이터 객체도 저장 가능, 자체적인 시맨틱 검색 기능 내장그래프 기반의 HNSW 인덱스를 주로 사용. 데이터 저장 시 자동으로 벡터화하는 모듈을 지원하며, GraphQL API를 통해 복합적인 쿼리가 가능
Milvus오픈소스, 대규모 벡터 검색을 위해 설계됨, 높은 확장성과 다양한 생태계 도구 지원다양한 인덱싱 유형(IVF_FLAT, HNSW 등)과 유사도 측정 지표(유클리드, 코사인 등)를 지원하여 사용자가 시나리오에 맞게 선택 가능

이 DB들의 공통점은 결국 (ID, Vector) 쌍을 저장하고, 주어진 벡터와 가장 유사한 벡터를 빠르게 찾아주는(k-NN 쿼리) 기능을 핵심으로 한다는 점이다.

차원

벡터 DB에서 차원은 데이터를 나타내는 벡터의 각 구성 요소를 의미하며, 데이터의 특정 특성이나 속성을 수치로 표현한 것이다.

하나의 데이터는 하나의 고차원 벡터로 변환된다. 예를 들어, '고양이'라는 단어는 [0.2, -0.4, 0.7]과 같은 3차원 벡터로 표현될 수 있으며, 여기서 각 숫자가 하나의 차원을 이룬다.

벡터 관리를 위한 자료구조

수백만, 수십억 개에 달하는 고차원 벡터들을 단순히 리스트나 배열에 담아두기만 해서는 효율적인 관리가 불가능하다. 특정 벡터와 유사한 벡터를 찾기 위해 모든 벡터와 일일이 비교하는 것은 엄청난 계산 비용을 초래하기 때문이다.

이 문제를 해결하기 위해 다양한 인덱싱 기법을 사용한다. 검색 및 인덱싱 기법들 보러가기

즉, 벡터 자체는 본질적으로 숫자 배열로 표현하나, 수많은 벡터의 집합을 효율적으로 관리하기 위해서는 단순 배열이 아닌, 고도화된 인덱싱 자료구조가 필수적이다.