본문 바로가기

RDB의 벡터 데이터와 임베딩 모델 (feat. Oracle, PostgreSQL)

@비오베베2026. 10. 16. 21:53

RDB의 벡터 데이터와 임베딩 모델 (feat. Oracle, PostgreSQL)

요즘 AI 관련 기술을 공부하다 보면 벡터(Vector), 임베딩(Embedding), 벡터 검색(Vector Search) 이라는 용어를 자주 접하게 됩니다.

처음에는 AI 모델 내부에서 사용하는 복잡한 데이터라고 생각했는데, 자세히 살펴보니 기존 RDB와도 밀접한 관련이 있었습니다.

특히 데이터베이스를 다루는 개발자라면 다음과 같은 질문이 생길 수 있습니다.

  • 기존 테이블에 벡터 데이터를 저장할 수 있을까?
  • 임베딩 모델은 DB 내부에서 실행하는 걸까, 외부에서 실행하는 걸까?
  • Oracle과 PostgreSQL은 벡터 데이터를 어떻게 처리할까?
  • 기존 SQL의 조건 검색과 벡터 검색은 무엇이 다를까?

이번 글에서는 이러한 궁금증을 중심으로 벡터 데이터와 임베딩 모델의 관계를 정리해 보겠습니다.

1. 벡터 데이터란?

일반적인 RDB에서는 문자열, 숫자, 날짜 등의 데이터를 컬럼에 저장합니다.

예를 들어 구매 서비스에서 상품 정보를 관리한다면 다음과 같이 구성할 수 있습니다.

상품 ID 상품명 가격
101 안전모 25,000
102 안전화 65,000
103 작업용 장갑 8,000

이 데이터는 상품 ID나 상품명 같은 명확한 조건으로 검색하기 좋습니다.

SELECT *
FROM PRODUCT
WHERE PRODUCT_NAME = '안전모';

그렇다면 사용자가 상품명을 정확히 입력하지 않고 다음과 같이 검색한다면 어떨까요?

공사 현장에서 머리를 보호할 수 있는 장비

문자열이 정확히 일치하지 않으므로 일반적인 조건 검색만으로는 '안전모'를 찾기 어려울 수 있습니다.

이때 활용할 수 있는 개념이 임베딩(Embedding) 입니다.

임베딩은 텍스트를 숫자 벡터로 변환하는 과정

임베딩 모델은 텍스트의 의미를 숫자들의 집합인 벡터로 표현합니다.

개념적으로는 다음과 같습니다.

입력 텍스트 변환된 벡터 예시
안전모 [0.12, 0.83, -0.21]
머리 보호 장비 [0.10, 0.79, -0.18]
사과 [-0.71, 0.14, 0.92]

위 숫자는 원리를 설명하기 위한 가상의 값입니다. 실제 임베딩은 모델에 따라 차원 수와 값이 달라집니다.

'안전모'와 '머리 보호 장비'는 의미가 비슷하므로 두 벡터도 유사한 방향을 가질 수 있습니다.

반면 '사과'처럼 의미가 다른 단어는 상대적으로 다른 벡터로 표현될 수 있습니다.

이렇게 만들어진 벡터 사이의 거리를 계산하면 텍스트의 의미가 얼마나 유사한지 비교할 수 있습니다.

다만 벡터가 비슷하다는 것이 반드시 문장의 의미가 완전히 같다는 뜻은 아닙니다. 실제 검색 결과는 임베딩 모델과 검색 기준에 영향을 받습니다.

2. 임베딩 모델과 RDB는 어떤 관계일까?

여기서 중요한 점이 하나 있습니다.

벡터 데이터를 저장하고 검색하는 기능과, 텍스트를 벡터로 변환하는 기능은 서로 다릅니다.

  • 임베딩 모델: 텍스트를 벡터로 변환합니다.
  • RDB: 벡터를 저장하고, 벡터 간 유사도를 계산하거나 검색합니다.

일부 DBMS는 지원되는 모델을 내부에 등록해 임베딩 생성까지 수행할 수 있습니다. 따라서 반드시 외부 모델을 사용해야 하는 것은 아닙니다.

방식 A. 외부 임베딩 모델을 사용하는 경우

일반적인 애플리케이션에서는 외부 API나 별도의 모델 서버를 호출해 임베딩을 생성할 수 있습니다.

graph TD
    A["Spring 애플리케이션"] -->|"텍스트 전달"| B["외부 임베딩 모델"]
    B -->|"벡터 반환"| A
    A -->|"벡터 저장"| C[("RDB")]
    D["사용자 검색어"] --> A
    A -->|"검색어 임베딩 생성"| B
    B -->|"검색 벡터 반환"| A
    A -->|"유사도 검색 SQL"| C
    C -->|"유사한 데이터 반환"| A

전체 흐름을 단계별로 정리하면 다음과 같습니다.

  1. 애플리케이션에서 원본 텍스트를 준비합니다.
  2. 외부 임베딩 모델에 텍스트를 전달합니다.
  3. 모델이 반환한 벡터를 RDB에 저장합니다.
  4. 사용자가 검색하면 검색어도 같은 방식으로 벡터로 변환합니다.
  5. RDB에서 저장된 벡터와 검색 벡터의 유사도를 비교합니다.
  6. 유사도가 높은 데이터를 조회합니다.

이 방식에서는 애플리케이션이 모델 호출과 DB 작업을 연결하는 역할을 담당합니다.

방식 B. DB 내부에서 임베딩 모델을 사용하는 경우

일부 DBMS에서는 모델을 등록하고 SQL을 통해 임베딩을 생성할 수 있습니다.

graph TD
    A["Spring 애플리케이션"] -->|"SQL 실행"| B[("Oracle Database 23ai")]
    B --> C["등록된 임베딩 모델 실행"]
    C --> D["벡터 생성"]
    D --> E["벡터 저장"]
    E --> F["벡터 유사도 검색"]
    F --> A

Oracle Database 23ai의 AI Vector Search 기능에서는 지원되는 ONNX 모델을 등록한 뒤 VECTOR_EMBEDDING 함수를 통해 임베딩을 생성하는 방식이 제공됩니다.

SELECT VECTOR_EMBEDDING(
           my_embedding_model
           USING '안전모 구매 방법' AS data
       ) AS embedding
FROM dual;

위 예제의 my_embedding_model은 실제 사용 전에 등록 및 설정해야 하는 모델 이름입니다. 모델 준비와 실행 환경 설정도 필요합니다.

두 방식의 차이는 다음과 같습니다.

구분 외부 모델 방식 DB 내부 모델 방식
임베딩 생성 외부 API 또는 모델 서버 DBMS 내부 기능
애플리케이션 역할 모델 호출 및 DB 작업 연결 SQL 실행 및 DB 작업 연결
모델 관리 외부 서비스에서 관리 DBMS의 지원 기능과 설정에 따름
고려할 점 API 호출 지연, 비용, 장애 대응 DBMS 버전, 모델 호환성, DB 자원 사용

어느 방식이 더 좋은지는 시스템 구조와 운영 환경에 따라 달라집니다. DB 내부에서 실행할 수 있다고 해서 모든 모델을 그대로 사용할 수 있는 것은 아닙니다.

3. Oracle과 PostgreSQL에서는 어떻게 사용할까?

벡터 데이터 지원 여부와 사용 방식은 DBMS 및 버전에 따라 다릅니다.

구분 Oracle Database 19c Oracle Database 23ai PostgreSQL + pgvector
벡터 전용 데이터 타입 VECTOR 타입 미지원 VECTOR 지원 vector 확장 타입
벡터 유사도 검색 별도 구현 필요 벡터 검색 기능 제공 pgvector 연산자 제공
임베딩 생성 일반적으로 외부 모델 사용 지원되는 모델을 DB에 등록해 생성 가능 일반적으로 외부 모델 사용
추가 구성 별도 설계 필요 모델 및 기능 설정 확인 pgvector 확장 설치

여기서 주의할 점은 PostgreSQL의 pgvector는 임베딩 모델이 아니라 벡터 데이터를 저장하고 검색하도록 돕는 확장 기능이라는 것입니다.

3-1. Oracle Database 23ai

Oracle Database 23ai에서는 VECTOR 타입으로 벡터 데이터를 저장할 수 있습니다.

CREATE TABLE AI_DOCUMENT (
    DOC_ID NUMBER PRIMARY KEY,
    DOC_CONTENT VARCHAR2(4000),
    EMBEDDING VECTOR(3, FLOAT32)
);

VECTOR(3, FLOAT32)는 3개의 실수형 요소를 가지는 벡터를 저장한다는 의미입니다.

벡터를 저장했다면 VECTOR_DISTANCE 함수를 사용해 검색 벡터와의 거리를 계산할 수 있습니다.

SELECT DOC_ID,
       DOC_CONTENT
FROM AI_DOCUMENT
ORDER BY VECTOR_DISTANCE(
    EMBEDDING,
    TO_VECTOR('[0.1, 0.2, 0.3]'),
    COSINE
)
FETCH FIRST 5 ROWS ONLY;

위 SQL은 예시 벡터와 코사인 거리를 비교해 가까운 데이터 5건을 조회합니다.

COSINE은 코사인 거리 계산을 의미하며, 여기서는 거리가 작은 순서대로 정렬합니다. 실제 서비스에서는 검색어를 임베딩 모델로 변환한 결과를 검색 벡터로 사용하게 됩니다.

Oracle Database 19c를 사용하고 있다면 위의 VECTOR 타입과 관련 SQL을 그대로 실행할 수 있다고 가정하면 안 됩니다. 데이터베이스 버전과 제공 기능을 먼저 확인해야 합니다.

3-2. PostgreSQL + pgvector

PostgreSQL에서는 pgvector 확장을 통해 벡터 데이터를 저장하고 검색할 수 있습니다.

먼저 확장을 활성화합니다.

CREATE EXTENSION vector;

그다음 벡터 컬럼을 포함한 테이블을 생성합니다.

CREATE TABLE items (
    id BIGINT PRIMARY KEY,
    content TEXT,
    embedding vector(3)
);

벡터 간 코사인 거리를 기준으로 가까운 데이터를 조회하는 SQL은 다음과 같습니다.

SELECT id,
       content
FROM items
ORDER BY embedding <=> '[0.1, 0.2, 0.3]'
LIMIT 5;

여기서 <=> 연산자는 코사인 거리를 계산합니다. 따라서 거리 값이 작은 데이터가 먼저 조회됩니다.

데이터가 많아지면 HNSW나 IVFFlat 같은 인덱스를 활용해 근사 최근접 이웃 검색을 구성할 수도 있습니다. 이러한 인덱스는 검색 속도와 검색 결과의 정확도 사이에 trade-off가 있으므로 데이터 규모와 요구사항에 맞게 선택해야 합니다.

4. 일반 SQL 검색과 벡터 검색은 무엇이 다를까?

두 방식은 서로 대체하는 관계라기보다 검색 목적이 다릅니다.

구분 일반 SQL 검색 벡터 검색
검색 기준 컬럼 값과 조건 벡터 간 거리 또는 유사도
대표적인 사용법 WHERE, JOIN 거리 연산자, 유사도 함수
강점 정확한 조건 검색, 관계 조회, 데이터 무결성 의미적으로 유사한 데이터 탐색
예시 상품명이 '안전모'인 데이터 안전모와 의미가 유사한 상품 설명

예를 들어 다음 SQL은 상품명이 정확히 일치하는 데이터를 찾습니다.

SELECT *
FROM PRODUCT
WHERE PRODUCT_NAME = '안전모';

반면 벡터 검색은 '머리를 보호하는 장비'라는 검색어와 의미적으로 가까운 상품을 찾는 데 활용할 수 있습니다.

실제 서비스에서는 두 방식을 결합하는 경우도 많습니다. 예를 들어 먼저 고객사나 상품 분류로 검색 대상을 제한하고, 그 안에서 벡터 유사도가 높은 데이터를 조회하는 식입니다.

5. AI 서비스에서는 RDB의 벡터 검색을 어떻게 활용할까?

대표적인 활용 사례로 RAG(Retrieval-Augmented Generation, 검색 증강 생성)가 있습니다.

RAG는 LLM이 답변을 생성하기 전에 관련 자료를 검색해 참고하도록 하는 방식입니다.

graph TD
    A["사용자 질문"] --> B["질문 임베딩 생성"]
    B --> C[("RDB 벡터 검색")]
    C --> D["관련 문서 검색 결과"]
    D --> E["질문과 문서를 LLM에 전달"]
    E --> F["답변 생성"]
    F --> G["사용자에게 응답"]

예를 들어 사내 구매 규정에 관한 질문에 답변하는 AI 서비스를 만든다고 가정해 보겠습니다.

  1. 구매 규정 문서를 작은 단위로 나눕니다.
  2. 각 문서 조각을 임베딩으로 변환해 DB에 저장합니다.
  3. 사용자가 질문하면 질문도 벡터로 변환합니다.
  4. 벡터 검색으로 관련 규정 문서를 찾습니다.
  5. 검색된 문서를 LLM에 전달해 답변을 생성합니다.

이 구조에서는 RDB가 단순히 데이터를 저장하는 역할을 넘어, AI가 참고할 정보를 검색하는 역할도 담당하게 됩니다.

다만 벡터 검색 결과가 관련 있다고 해서 항상 정답인 것은 아닙니다. 문서의 최신성, 접근 권한, 검색 결과의 품질과 LLM의 답변 생성 과정도 함께 관리해야 합니다.

6. 개발자 관점에서 기억할 점

벡터 검색을 도입하더라도 기존 RDB의 역할이 사라지는 것은 아닙니다.

오히려 기존 데이터와 벡터를 어떻게 연결하고 관리할지가 중요합니다.

  • 원본 데이터와 연결: 벡터가 어떤 상품, 문서, 게시글에서 생성되었는지 식별할 수 있어야 합니다.
  • 변경 데이터 관리: 원본 내용이 변경되면 임베딩을 다시 생성해야 할 수 있습니다.
  • 접근 권한 관리: 벡터 검색 결과에도 고객사, 사용자, 문서별 접근 권한을 적용해야 합니다.
  • 검색 성능 관리: 데이터 규모에 따라 인덱스와 검색 조건을 검토해야 합니다.
  • 모델 변경 관리: 임베딩 모델을 변경하면 기존 벡터와 새 벡터의 호환성을 확인해야 합니다.

특히 여러 고객사가 하나의 시스템을 공유하는 SaaS 환경이라면, 유사도 검색만 고려해서는 안 됩니다. 검색 대상의 고객사와 권한을 정확히 제한하는 것 역시 중요한 설계 요소입니다.

마무리

이번에 살펴본 내용을 정리하면 다음과 같습니다.

  • 임베딩 모델은 텍스트를 벡터로 변환합니다.
  • RDB는 벡터를 저장하고 유사도를 계산해 관련 데이터를 검색할 수 있습니다.
  • 임베딩 모델은 외부에서 실행할 수도 있고, 지원되는 DBMS에서는 내부에서 실행할 수도 있습니다.
  • Oracle Database 23ai는 벡터 검색 기능을 제공하고, PostgreSQL은 pgvector 확장을 활용할 수 있습니다.
  • RDB의 정확한 조건 검색과 벡터 검색을 결합하면 AI 서비스에서 활용할 수 있는 검색 구조를 만들 수 있습니다.

개인적으로는 벡터 검색을 완전히 새로운 데이터베이스 기술로 보기보다는, 기존 데이터와 관계형 구조 위에 의미 기반 검색 기능을 더하는 방식으로 이해하면 접근하기 쉬운 것 같습니다.

앞으로 AI 서비스를 개발할 때도 모델의 기능만 살펴보는 것이 아니라, 생성된 벡터를 어떻게 저장하고 관리하며 기존 데이터와 연결할지 함께 고민할 필요가 있겠습니다.


참고 자료

  1. Oracle AI Vector Search User's Guide
  2. Oracle Database — VECTOR_EMBEDDING
  3. Oracle Blog — Getting Started with Oracle Database 23ai AI Vector Search
  4. pgvector 공식 GitHub 저장소 및 사용법
비오베베
@비오베베 :: 생각하는 개발자

부득탐승

목차