한 줄 핵심

PostgreSQL은 데이터가 저장되는 “창고 그 자체”이고, SQLAlchemy는 그 창고를 Python 언어로 편하게 관리하게 해주는 “통역사”이며, pgvector는 창고에 벡터 전용 선반을 추가해 주는 “확장 부품”이다. 세 가지는 경쟁 관계가 아니라 층이 다른 협력 도구.

포함 관계

Python 애플리케이션
   │
   └─ SQLAlchemy (ORM 라이브러리)
        │
        └─ psycopg2 같은 드라이버
             │
             └─ PostgreSQL (DB 서버)
                  └─ pgvector (확장 기능, 벡터 타입/인덱스 추가)

위에서 아래로 내려갈수록 “더 낮은 층, DB에 가까운 층”이다. SQLAlchemy는 PostgreSQL을 포함하는 게 아니라 PostgreSQL 위에서 대화하는 Python 쪽 도구임.


1. PostgreSQL (DBMS, Database Management System)

데이터를 실제로 저장/수정/삭제하는 프로그램 그 자체다.

  • 역할: 하드 드라이브에 데이터를 안전하게 보관하고 관리한다
  • 언어: 데이터 조작을 위해 **SQL(Structured Query Language, 표준 데이터베이스 언어)**을 사용
  • 실행 위치: 데이터베이스 서버에서 독립 프로세스로 상주
  • 예시 쿼리: SELECT * FROM users;

2. SQLAlchemy (ORM, Object Relational Mapping)

Python 객체와 DB 테이블을 자동 매핑해 주는 **라이브러리(파이썬 패키지)**다.

  • 역할: SQL을 직접 쓰지 않고 Python 클래스/객체를 다루듯 데이터를 처리하게 해준다
  • 장점: 코드가 간결해지고, DB를 PostgreSQL → MySQL 등으로 교체해도 수정 범위가 작음
  • 실행 위치: 애플리케이션(Python) 프로세스 내부
  • 예시 코드: session.query(User).all()

주요 차이 비교

구분PostgreSQLSQLAlchemy
정체데이터베이스 서버/소프트웨어Python 라이브러리
주요 언어SQLPython
실행 위치별도 DB 서버 프로세스애플리케이션 프로세스
설치서버 설치(예: apt install postgresql)pip install sqlalchemy
비유책이 꽂혀 있는 도서관책을 대신 찾아오는 사서

둘이 같이 동작하는 순서

[개발자]
  user.save()  ← Python 객체 조작
     │
     ▼
[SQLAlchemy]
  "저장해달라는 뜻이구나"
  → INSERT INTO users ... 로 자동 번역
     │
     ▼ (TCP 연결로 전송)
     │
[PostgreSQL]
  SQL 수신 → 디스크에 실제 저장
  → 결과 반환

1단계: 개발자가 Python으로 user.save() 호출 2단계: SQLAlchemy가 그 호출을 적절한 SQL 문자열로 번역 3단계: 드라이버(psycopg2 등)가 SQL을 TCP 패킷으로 감싸 전송 4단계: PostgreSQL이 실제 디스크 I/O 수행 후 결과 반환


pgvector (PostgreSQL의 벡터 확장)

**PostgreSQL이라는 창고에 “벡터(Vector, 숫자 배열 형태의 의미 좌표) 데이터”를 저장할 수 있는 선반을 추가해 주는 Extension(확장 기능)**이다.

pgvector가 하는 구체적 일

일반 컬럼은 “값이 같은가?”를 묻지만, pgvector는 **“얼마나 비슷한가?”**를 묻게 해준다.

  • 벡터 타입(Type) 제공: [0.1, -0.2, 0.5, ...] 같은 실수 배열을 vector(1536) 같은 컬럼에 저장 가능
  • 유사도 계산 연산자: 아래 표의 연산자로 “가장 가까운 이웃(Nearest Neighbor)” 검색
  • 인덱싱(Indexing, 검색 지름길): HNSW, IVFFlat 인덱스로 수백만 건이어도 순식간에 탐색

pgvector 거리 연산자

연산자거리 종류주 용도
<->L2 거리(유클리드)기본 거리 측정
<#>음의 내적(Inner Product)정규화 벡터 비교
<=>코사인 거리(Cosine)OpenAI 임베딩 등 기본값
<+>L1 거리(맨해튼)드물게 사용

인덱스 방식 비교

관점HNSWIVFFlat
검색 속도빠름보통
빌드 시간오래 걸림빠름
메모리 사용많음적음
데이터 추가 시자동 반영리빌드 권장
추천 규모대규모 프로덕션중소규모

왜 별도 벡터 DB(Pinecone, Milvus) 대신 pgvector를 쓰나

  • 통합 관리: 사용자 이름(문자), 가입일(날짜), AI 임베딩(벡터)을 한 테이블에 넣고 한 쿼리로 조회 가능
  • 학습 비용 절감: 이미 아는 SQLAlchemy를 그대로 재활용
  • 운영 단순화: 관리할 DB 서버 개수가 하나로 유지됨

SQLAlchemy와 pgvector가 함께 동작할 때

[AI 임베딩 단계]
  "사과" → OpenAI API → [0.12, 0.85, ...] (1536차원 벡터)
     │
     ▼
[SQLAlchemy]
  Vector 타입 컬럼으로 감싸서
  INSERT INTO items (name, embedding) VALUES ('사과', '[0.12, 0.85, ...]')
     │
     ▼
[PostgreSQL + pgvector]
  디스크에 저장
  → 검색 시 "<=>" 연산자로 코사인 거리 계산
  → "포도"보다 "배"가 더 가깝다고 판단

SQLAlchemy에서 pgvector 쓰는 최소 코드

from sqlalchemy import Column, Integer, String
from sqlalchemy.orm import declarative_base
from pgvector.sqlalchemy import Vector
 
Base = declarative_base()
 
class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, primary_key=True)
    name = Column(String)
    embedding = Column(Vector(1536))  # OpenAI text-embedding-3-small 차원

직접 확인

-- PostgreSQL에 접속 후 확장 활성화 (관리자 권한 필요)
CREATE EXTENSION IF NOT EXISTS vector;
 
-- 확장 설치 확인
SELECT * FROM pg_extension WHERE extname = 'vector';

한마디 요약

PostgreSQL은 서버, SQLAlchemy는 Python 쪽 통역사, pgvector는 서버 안에 덧붙는 벡터 선반이다. 세 가지가 층층이 협력해 “AI 벡터 검색 + 기존 RDB 기능”을 한 번에 제공함.

관련 노트